这题通过率不是很高,所以把自己的代码贴在这,供大家交流!
我的解题思路:总共n种糖果,每种a[i]个。那么可以这样解决问题。如果某种糖果个数越多则先吃。比如5种糖果,个数如下5 1 1 1 1。如果先吃个数为1的糖果,那么个数
为5的那种糖果肯定吃不完;如果先吃个数为5的那种糖果,那么将能够吃完。(个人理解,无法确切证明!!!)
代码大概:①用堆排序按每种糖果个数减排序排列a[n]。②函数judge_eat()则来判断能否吃完。方法是:tem用来记录每两种吃剩下的糖果,开始赋值为0。如果tem>=a[i],
则tem=tem-a[i];反之,tem=a[i]-tem-1。比如上个例子:①tem=0,a[1]=5,a[1]中糖果将被吃去一个,tem=a[i]-tem-1=5-0-1=4。②tem和a[2]比较。tem=4>=a[2]=1,a[2]中糖
果将被全部吃掉,tem中也将吃去a[2]个(最后吃的是tem中的糖果,就像我有2个苹果,你有2个,你先吃,最后肯定是我吃的,当然前提是我的苹果个数不小于你的。这决定
了我吃的苹果个数和你吃的相同),此时tem=tem-a[2]-1=4-1=3。③a[3]=1,同理tem=tem-a[3]=3-a[3]=3-1=2。④a[4]=1,tem=tem-a[4]=2-1=1。⑤a[5]=1,最后a[5]先被吃,再
吃tem中最后一个。
课件,吃糖果的原则:1、先吃个数最多的哪一种;2、每次比较都首先吃a[i]中的糖果,因为上一次最后吃的是tem中的糖果;③满足题目条件时能吃就吃。
代码:
#include<iostream>
using namespace std;
void shift(int a[],int k,int m) //调整堆
{
int i=k,j=2*i,tem=a[k];
bool finished=false;
while(j<=m && !finished)
{
if(j<m && a[j+1]<a[j])
j++;
if(tem<=a[j])
finished=true;
else
{
a[i]=a[j];
i=j;
j*=2;
}
}
a[i]=tem;
}
void heap_sort(int a[],int n) //堆排序
{
int i,tem;
for(i=n/2;i>=1;i--)
shift(a,i,n);
for(i=n;i>=2;i--)
{
tem=a[1];
a[1]=a[i];
a[i]=tem;
shift(a,1,i-1);
}
}
bool deal_eat(int a[],int n) //处理吃的结果
{
int tem=0;
for(int i=1;i<=n;i++)
{
if(tem<a[i])
tem=a[i]-tem-1;
else
tem-=a[i];
}
if(tem==0)
return true;
return false;
}
int buffer[1000001];
int main()
{
int i,n,t;
cin>>t;
while(t--)
{
cin>>n;
for(i=1;i<=n;i++)
cin>>buffer[i];
heap_sort(buffer,n);
bool judge=deal_eat(buffer,n);
if(judge)
cout<<"Yes";
else
cout<<"No";
cout<<endl;
}
return 0;
}