题目大意:
有n个团和很多盒糖,每个团中人数不一定相同,每盒糖中都有p颗糖。
现在要给每个团发糖,要求每个人都要发到糖,只有一盒糖发完后才能发下一盒糖。
发糖的顺序可以任意安排,问经过合理安排后,最多能让几个团吃到新开的糖。
思路:
分类讨论+贪心。
讨论p的不同取值。
对于p=2时,如果人数是偶数,就肯定能满足,如果是奇数就两两配对,满足其中的一组。
对于p=3时,如果刚好能被3整除,就肯定能满足,剩下余数为1的和余数为2的配对,再剩下来的每三组能满足一组。
对于p=4时,如果刚好能被3整除,就肯定能满足,剩下余数为2的尽量和自己配对,余数为1的尽量和3配对。
剩下来1和3的只会有一种,然后和2配对即可。
一开始考试时全想到了,不过p=3的时候,对于1和2配对的情况,当时没想清楚,以为能满足两组。
p=4的时候对于剩下的情况打表,似乎也打挂了。
然后就只拿了30分。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 int main() { 12 int T=getint(); 13 for(register int t=1;t<=T;t++) { 14 int n=getint(),p=getint(); 15 if(p==2) { 16 int ans=0,cnt=0; 17 for(register int i=1;i<=n;i++) { 18 if(getint()&1) { 19 cnt++; 20 } else { 21 ans++; 22 } 23 } 24 printf("Case #%d: %d ",t,ans+((cnt+1)>>1)); 25 continue; 26 } 27 if(p==3) { 28 int cnt1=0,cnt2=0,ans=0; 29 for(register int i=1;i<=n;i++) { 30 const int x=getint(); 31 if(!(x%3)) ans++; 32 if(x%3==1) cnt1++; 33 if(x%3==2) cnt2++; 34 } 35 if(cnt1==cnt2) { 36 ans+=cnt1; 37 } 38 if(cnt1<cnt2) { 39 ans+=cnt1+(cnt2-cnt1)/3; 40 if((cnt2-cnt1)%3) ans++; 41 } 42 if(cnt2<cnt1) { 43 ans+=cnt2+(cnt1-cnt2)/3; 44 if((cnt1-cnt2)%3) ans++; 45 } 46 printf("Case #%d: %d ",t,ans); 47 continue; 48 } 49 if(p==4) { 50 int cnt1=0,cnt2=0,cnt3=0,ans=0; 51 for(register int i=1;i<=n;i++) { 52 const int x=getint(); 53 if(!(x&3)) ans++; 54 if((x&3)==1) cnt1++; 55 if((x&3)==2) cnt2++; 56 if((x&3)==3) cnt3++; 57 } 58 ans+=cnt2>>1; 59 cnt2&=1; 60 int min=std::min(cnt1,cnt3); 61 ans+=min; 62 cnt1-=min; 63 cnt3-=min; 64 if(cnt2&&cnt1>=2) { 65 ans++; 66 cnt1-=2; 67 cnt2=0; 68 } 69 if(cnt2&&cnt3>=2) { 70 ans++; 71 cnt3-=2; 72 cnt2=0; 73 } 74 if(cnt2) { 75 ans++; 76 } else { 77 ans+=(cnt1+3)>>2; 78 ans+=(cnt3+3)>>2; 79 } 80 printf("Case #%d: %d ",t,ans); 81 continue; 82 } 83 } 84 return 0; 85 }