先上题目
HOHO,终于从Speakless手上赢走了所有的糖果,是Gardon吃糖果时有个特殊的癖好,就是不喜欢将一样的糖果放在一起吃,喜欢先吃一种,下一次吃另一种,这样;可是Gardon不知道是否存在一种吃糖果的顺序使得他能把所有糖果都吃完?请你写个程序帮忙计算一下。
Input第一行有一个整数T,接下来T组数据,每组数据占2行,第一行是一个整数N(0<N<=1000000),第二行是N个数,表示N种糖果的数目Mi(0<Mi<=1000000)。
Output对于每组数据,输出一行,包含一个"Yes"或者"No"。
Sample Input
2 3 4 1 1 5 5 4 3 2 1
Sample Output
No Yes
——————————————————————————————————————————————————————————————————————————————————————————
一开始的思路是建立一个数组,然后快排,之后循环一个个减一,如果最后只剩下一种糖果,并且只剩下一颗,那就是Yes。不过!超时了(其实自己心里也有B数会超时)。
后面发现了鸽巢原理.
思路:
把 最大数的糖果 每两个中间隔开一个空,假设最大数为n,所以中间就有了n-1个空。
然后就可以把其它的 糖果 一种种,插入空中。
也就是说 如果 空 能 填满,那就成立,不然就炸了。
所以 其它的糖果的总数 >= 最大数的糖果-1,就成立了。
例如5 4 3 2 1
那就可以 分成 5——5——5——5——5
然后插空 54——54——54——54——5
再插空 543——543——543——54——5
接着 5432——5432——543——54——5
最后 54321——5432——543——54——5
OK,就是这样了!下面贴代码。
#include<algorithm> #include<iostream> #include<cstdio> #include<set> using namespace std; int T,n; long long Max,sum;//数据避免太大用longlong int num[1000005]; int main() { cin>>T; while(T--){ cin>>n; Max=sum=0; for(int i=1;i<=n;i++){ scanf("%d",&num[i]); sum+=num[i]; if(Max<num[i]){ Max=num[i]; } } sum-=Max; Max--; if(sum>=Max){ cout<<"Yes"<<endl; } else{ cout<<"No"<<endl; } } return 0; }