[GCJ2017R2]Fresh Chocolate

题目大意:
  有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\n",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\n",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\n",t,ans);
81             continue;
82         }
83     }
84     return 0;
85 }

 

posted @ 2017-10-08 15:16  skylee03  阅读(123)  评论(0编辑  收藏  举报