codeforces 214B
【题意描述】
本题就是在给定的n个整数中选出若干个数字组成一个最大数并且能被2,3,5整除。
【解题思路】
我们在求最大数是否能被2,3,5整除时,首先应该满足n个数字里面必须有0,如果没有,是不能构成最大数的。当有0以后,我们需要了解一个知识,那就是一个数字乘以10的n次方后除3的余数仍然是原来那个数字。那么我们就可以研究这n个数字与3的关系,进而研究整体。如果这n个数字加起来的整体之和除3的余数为1,那么我们需要删除一个余数为1的数(该数尽量小),或者删除两个余数为2的数字(这两个数字尽量小);当和除3的余数为2时,我们需要删除一个余数为2的数字(该数尽量小),活着的删除两个余数为1的数字(这两个数字尽量小)。
【AC代码】
代码1:优势,代码简单易读;缺点:所开数组过大,不节约空间
1 #include<iostream> 2 #include<algorithm> 3 #include<string.h> 4 using namespace std; 5 #define max 100005 6 int num[max]; 7 int l[max]; 8 int vis[max]; 9 int num_zero; 10 int cmp(int a,int b) 11 { 12 return a>b; 13 } 14 int main() 15 { 16 int n; 17 while(cin>>n) 18 { 19 int judge=0; 20 memset(vis,1,sizeof(vis)); 21 for(int i=0;i<n;i++) 22 { 23 cin>>num[i]; 24 if(num[i]==0) judge=1; //记录0的个数 25 } 26 if(!judge) {cout<<-1<<endl;continue;} 27 else 28 { 29 sort(num,num+n,cmp);//排序 30 int sum_total=0; 31 int left_one=0,left_zero=0,left_two=0; 32 for(int i=0;i<n;i++) 33 { 34 l[i]=num[i]%3; 35 if(l[i]==2) 36 left_two++; 37 else if(l[i]==1) 38 left_one++; 39 else if(l[i]==0) 40 left_zero++; 41 sum_total+=l[i]; 42 } 43 int sum_left=sum_total%3; 44 if(sum_left==0)//直接被整除 45 { 46 if(num[0]==0) cout<<0<<endl; 47 else 48 for(int i=0;i<n;i++) 49 cout<<num[i]; 50 cout<<endl; 51 } 52 else if(sum_left==1)//余数为1 53 { 54 55 if(left_one==0) 56 { 57 for(int i=n-1,count1=0;i>=0;i--) 58 { 59 if(l[i]==2) {count1++;vis[i]=0;} 60 if(count1==2) break; 61 } 62 } 63 if(left_one!=0) 64 { 65 for(int i=n-1;i>=0;i--) 66 if(l[i]==1){vis[i]=0;break;} 67 } 68 int count_vis=0; 69 for(int i=0;i<=n-1;i++)//寻找最后剩下的数字是否有正数 70 if(vis[i]&&num[i]>0) count_vis++; 71 if(count_vis==0) cout<<0<<endl; 72 else 73 {for(int i=0;i<n;i++) 74 if(vis[i]) cout<<num[i]; 75 cout<<endl; 76 } 77 } 78 else if(sum_left==2) 79 { 80 if(left_two!=0) 81 { 82 for(int i=n-1;i>=0;i--) 83 if(l[i]==2){vis[i]=0;break;} 84 } 85 if(left_two==0) 86 { 87 for(int i=n-1,count2=0;i>=0;i--) 88 { 89 if(l[i]==1) {count2++;vis[i]=0;} 90 if(count2==2) break; 91 } 92 } 93 int count_vis1=0; 94 for(int i=0;i<n;i++) 95 if(vis[i]&&num[i]>0) count_vis1++; 96 if(count_vis1==0) cout<<0<<endl; 97 else 98 { 99 for(int i=0;i<n;i++) 100 if(vis[i]) cout<<num[i]; 101 cout<<endl; 102 } 103 } 104 105 } 106 } 107 return 0; 108 }
代码2:优点:所开空间小,技巧性强
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 int main() 8 { 9 int n,d[10]; 10 while(scanf("%d",&n)!=EOF) 11 { 12 int i,j,sum=0,a; 13 memset(d,0,sizeof(d)); 14 for(i=0; i<n; i++) 15 { 16 scanf("%d",&a); 17 sum+=a; 18 d[a]++; 19 } 20 if(d[0]==0) printf("-1\n"); 21 else 22 { 23 int flag=0; 24 if(sum%3==1) 25 { 26 if(d[1]+d[4]+d[7]) 27 { 28 for(i=1; i<=7; i+=3) 29 if(d[i]) {d[i]--,sum-=i;break;} 30 } 31 else if(d[2]+d[5]+d[8]>=2) 32 for(j=1,i=2; i<=8; i+=3) 33 while(d[i]&&j<=2) 34 {d[i]--,sum-=i,j++;} 35 } 36 if(sum%3==2) 37 { 38 if(d[2]+d[5]+d[8]) 39 { 40 for(i=2; i<=8; i+=3) 41 if(d[i]) {d[i]--,sum-=i;break;} 42 } 43 else if(d[1]+d[4]+d[7]>=2) 44 for(j=1,i=1; i<=7; i+=3) 45 while(d[i]&&j<=2) {d[i]--,sum-=i,j++;} 46 } 47 48 if(!flag) 49 { 50 if(d[1]+d[2]+d[3]+d[4]+d[5]+d[6]+d[7]+d[8]+d[9]) 51 { 52 for(i=9; i>=0; i--) 53 while(d[i]--) printf("%d",i); 54 printf("\n"); 55 } 56 else printf("0\n"); 57 } 58 } 59 60 } 61 62 return 0; 63 }