HDU 1205
先上題目
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個空。
然後就可以把其它的 糖果 一種種,插入空中。
也就是說 如果 空 能 填滿,那就成立,不然就炸了。
所以 其它的糖果的總數 >= 最大數的糖果,就成立了。
例如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<stdio.h>
#include<stdlib.h>
int a[1000010];
int main()
{
int x;
scanf("%d", &x);
while (x--)
{
memset(a, 0, sizeof(a));
int n,max=0;
long long sum = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
sum += a[i];
if (a[i] > max) { max = a[i]; }
}
sum -= max;
max--;
if (max <= sum) { printf("Yes\n"); }
else
{
printf("No\n");
}
}
return 0;
}
HDU 1205