这题通过率不是很高,所以把自己的代码贴在这,供大家交流!
我的解题思路:总共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; }