POJ 1013 Counterfeit Dollar 称硬币
12个硬币,有一个假的 或轻或重,找出假硬币
开始用的模拟,考虑很多情况
后来,lmy说轻的-1,重的+1,学数学的看什么都是数字,orz
模拟写的两个差不多的代码:
(一)
#include<iostream> #include<cstdio> #include<string> #include<cstring> using namespace std; int vs[15],cnt[15]; int main() { int CASE,ca,len,i,x,sum; char s1[15],s2[15],s3[8]; scanf("%d",&CASE); while(CASE--) { sum=0; memset(vs,0,sizeof(vs)); memset(cnt,0,sizeof(cnt)); for(ca=1;ca<=3;ca++) { scanf("%s%s%s",s1,s2,s3); len=strlen(s1); if(s3[0]=='e')//一定是真的 { for(i=0;i<len;i++) { x=s1[i]-'A'; vs[x]=1; x=s2[i]-'A'; vs[x]=1; } } if(s3[0]=='u')//前重后轻 { sum++; len=strlen(s1); for(i=0;i<len;i++) { x=s1[i]-'A'; if(!vs[x]){vs[x]=3;cnt[x]=1;} else if(vs[x]==2)vs[x]=1; else if(vs[x]==3)cnt[x]++; x=s2[i]-'A'; if(!vs[x]){vs[x]=2;cnt[x]=1;} else if(vs[x]==3)vs[x]=1; else if(vs[x]==2)cnt[x]++; } } if(s3[0]=='d')//前轻后重 { sum++; len=strlen(s1); for(i=0;i<len;i++) { x=s1[i]-'A'; if(!vs[x]){vs[x]=2;cnt[x]++;} else if(vs[x]==3)vs[x]=1; else if(vs[x]==2)cnt[x]++; x=s2[i]-'A'; if(!vs[x]){vs[x]=3;cnt[x]++;} else if(vs[x]==2)vs[x]=1; else if(vs[x]==3)cnt[x]++; } } } int mark; for(i=0;i<12;i++) { if(vs[i]!=1&&cnt[i]==sum)//vs不能去掉 { mark=i; break; } } if(vs[mark]==3) printf("%c is the counterfeit coin and it is heavy.\n", mark+'A'); if(vs[mark]==2) printf("%c is the counterfeit coin and it is light.\n", mark+'A'); } return 0; }
(二)
#include<iostream> #include<cstdio> #include<string> #include<cstring> using namespace std; int vs[15],cnt[15]; int main() { int CASE,ca,len,i,x,sum; char s1[15],s2[15],s3[8]; scanf("%d",&CASE); while(CASE--) { sum=0; memset(vs,0,sizeof(vs)); memset(cnt,0,sizeof(cnt)); for(ca=1;ca<=3;ca++) { scanf("%s%s%s",s1,s2,s3); len=strlen(s1); if(s3[0]=='e')//一定是真的 { for(i=0;i<len;i++) { x=s1[i]-'A'; vs[x]=1,cnt[x]=0;//必须写上cnt[x]=0,因为可能第二组或第三组 x=s2[i]-'A'; vs[x]=1,cnt[x]=0; } } if(s3[0]=='u')//前重后轻 { sum++; len=strlen(s1); for(i=0;i<len;i++) { x=s1[i]-'A'; if(!vs[x]){vs[x]=3;cnt[x]=1;} else if(vs[x]==2){vs[x]=1;cnt[x]=0;} else if(vs[x]==3)cnt[x]++; x=s2[i]-'A'; if(!vs[x]){vs[x]=2;cnt[x]=1;} else if(vs[x]==3){vs[x]=1;cnt[x]=0;} else if(vs[x]==2)cnt[x]++; } } if(s3[0]=='d')//前轻后重 { sum++; len=strlen(s1); for(i=0;i<len;i++) { x=s1[i]-'A'; if(!vs[x]){vs[x]=2;cnt[x]++;} else if(vs[x]==3){vs[x]=1;cnt[x]=0;} else if(vs[x]==2)cnt[x]++; x=s2[i]-'A'; if(!vs[x]){vs[x]=3;cnt[x]++;} else if(vs[x]==2){vs[x]=1;cnt[x]=0;} else if(vs[x]==3)cnt[x]++; } } } int mark; for(i=0;i<12;i++) { if(cnt[i]==sum)//vs[i]!=1去掉了 { mark=i; break; } } if(vs[mark]==3) printf("%c is the counterfeit coin and it is heavy.\n", mark+'A'); if(vs[mark]==2) printf("%c is the counterfeit coin and it is light.\n", mark+'A'); } return 0; }
(三)转成数学加减后的简单代码!!!
#include<iostream> #include<cstdio> #include<string> #include<cstring> using namespace std; int cnt[15]; bool vs[15]; int main() { int CASE,ca,len,i,x,sum; char s1[15],s2[15],s3[8]; scanf("%d",&CASE); while(CASE--) { sum=0; memset(cnt,0,sizeof(cnt)); memset(vs,0,sizeof(vs)); for(ca=1;ca<=3;ca++) { scanf("%s%s%s",s1,s2,s3); len=strlen(s1); if(s3[0]=='u')//前重后轻 { sum++; for(i=0;i<len;i++) { x=s1[i]-'A'; if(!vs[x]) cnt[x]++; } for(i=0;i<len;i++) { x=s2[i]-'A'; if(!vs[x]) cnt[x]--; } } if(s3[0]=='d')//前轻后重 { sum++; for(i=0;i<len;i++) { x=s1[i]-'A'; if(!vs[x]) cnt[x]--; } for(i=0;i<len;i++) { x=s2[i]-'A'; if(!vs[x]) cnt[x]++; } } if(s3[0]=='e')//相等 { for(i=0;i<len;i++) { x=s1[i]-'A'; cnt[x]=0; vs[x]=1; } for(i=0;i<len;i++) { x=s2[i]-'A'; vs[x]=1; cnt[x]=0; } } } int mark; for(i=0;i<12;i++) { if(!vs[i]) if(cnt[i]==sum||cnt[i]==-sum) { mark=i; break; } } if(cnt[mark]>0) printf("%c is the counterfeit coin and it is heavy.\n", mark+'A'); if(cnt[mark]<0) printf("%c is the counterfeit coin and it is light.\n", mark+'A'); } return 0; }