POJ 1013 Counterfeit Dollar
題意:有一打硬幣,其中有一個是假幣,質量可能較輕,也可能較重。通過三次稱重將假幣找出。
由於計算機很難模仿人的想法來實現問題。這道題我糾結了很久。
最後我是通過一一枚舉的笨方法做的。就是從A硬幣開始到L硬幣結束,一一假設其為假幣,其中又分為輕和重。當符合三次稱重之後便找到了假幣。
後來看網上有人是將三次稱重這樣實現的:給這十二枚硬幣賦初值。如果是even,那麼硬幣值不變。如果是up,那麼左邊的自加,右邊的自減。由於對於不確定的硬幣還要做下一次測試。所以通過三次測試之後,偏離初值最大的必然為假幣
#include<iostream> #include<cstdio> #include<cstring> #include<string> using namespace std; int main () { int n,i,j,k; cin>>n; while(n--) { char al[3][20],ar[3][20],a[3][10]; int v[15]= {0},visit[15]= {0}; bool flag=true; for (i=0; i<3; i++) cin>>al[i]>>ar[i]>>a[i]; for (i=0; i<24; i++) { flag=true; v[i/2]=(i%2==0?-1:1); for (k=0; k<3; k++) { int left=0,right=0; for (j=0; j<strlen(al[k]); j++) left+=v[al[k][j]-'A']; for (j=0; j<strlen(ar[k]); j++) right+=v[ar[k][j]-'A']; if (strcmp(a[k],"even")==0 && left!=right) flag=false; if (strcmp(a[k],"up")==0 && !(left>right)) flag=false; if (strcmp(a[k],"down")==0 && !(left<right)) flag=false; } v[i/2]=0; if (flag) break; } if (!(i%2)) printf("%c is the counterfeit coin and it is light. \n",i/2+'A'); else printf("%c is the counterfeit coin and it is heavy. \n",i/2+'A'); } return 0; }