1. 程式人生 > >HDU 1205

HDU 1205

less input out ont -- cli output 假設 表示

先上題目

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