2 条题解

  • 0
    @ 2026-6-25 9:41:00

    这道题的难点:想到二分

    先审一遍题,发现可以这么处理:先造出 sumsum 个恰好包含 nn 颗珠子的项链,(不难看出这个 sumsum 就是 min1knakmin_{1≤k≤n} a_k)再归还 sumsum 颗珠子,使得剩下的珠子能够造出最多的恰好包含 n1n-1 颗珠子的项链,设为 xx

    具体实现:先把所有的 aia_i 从小到大排序,这样最小值便是 a1a_1,将所有的 aia_i减去这个最小值,这样 a1a_1 就会变为 00,之后我们就不用管它了。归还 sumsum 颗珠子的时候,只需要考虑 a2a_2ana_n 就行了。考虑具体如何归还,注意到,xx 的最大值其实就是归还完后 a2a_2ana_n 的最小值,由于具体归还策略比较难考虑,可以二分答案

    下面是代码:

    #include<bits/stdc++.h>
    using namespace std;
    long long a[59];
    long long n;
    bool flag=0;
    bool check(long long x,long long sum){
    	for(long long i=2;i<=n;i++)//check逻辑:如果归还sum颗珠子能够支持再造x个包含n-1颗珠子的项链,返回1,否则返回0 
    		if(a[i]<x)
    			if(x-a[i]>sum)
    				return 0;
    			else
    				sum-=x-a[i];
    	return 1;
    }
    int main(){
    	scanf("%lld",&n);
    	for(long long i=1;i<=n;i++)
    		scanf("%lld",&a[i]);
    	sort(a+1,a+n+1);
    	long long sum=a[1];
    	for(long long i=1;i<=n;i++)//先造sum个包含n颗珠子的项链 
    		a[i]-=sum;
    	long long l=0,r=1000000000;//二分上界其实没那么大,不过我懒得改了
    	while(l+1<r){//二分答案 
    		long long mid=(l+r)>>1;
    		if(check(mid,sum))
    			l=mid;
    		else
    			r=mid;
    	}
    	printf("%lld\n",l+sum);
    	return 0;
    }
    
    

    整体复杂度O(nlogn)

    信息

    ID
    278
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    (无)
    递交数
    12
    已通过
    6
    上传者