题目链接:
POJ 1013 http://poj.org/problem?id=1013
百炼 假币问题 http://bailian.openjudge.cn/practice/2692/
题目大意
有12枚硬币。其中有11枚真币和1枚假币。假币和真币重量不同,但不知道假币比真币轻还是重。现在,用一架天平称了这些币三次,告诉你称的结果,请你找出假币并且确定假币是轻是重(数据保证一定能找出来)。
输入
第一行是测试数据组数。
每组数据有三行,每行表示一次称量的结果。银币标号为A-L。每次称量的结果用三个以空格隔开的字符串表示:天平左边放置的硬币、天平右边放置的硬币、平衡状态。其中平衡状态用``up'', ``down'', 或 ``even''表示, 分别为右端高、右端低和平衡。天平左右的硬币数总是相等的。
输出
输出哪一个标号的银币是假币,并说明它比真币轻还是重 。
输入样例
1
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even
输出样例
K is the counterfeit coin and it is light.
解题思路
第一种代码
每一枚硬币有三种状态:较重的假币、较轻的假币、真硬币。
由于只有一枚假币,且总共只有12枚硬币,因此可以把所有硬币的所有状态都枚举一遍,对每一种假设的情况进行验证:若是某种假设符合输入的三个条件,那么该假设就是成立的。
1 #include<stdio.h> 2 int status[12]={0};//表示12枚硬币的真假状态:0为真,-1为假币且假币较轻,1为假币且假币较重 3 char left[3][7],right[3][7],result[3][7]; 4 bool Balanced();//判断某种假设是否合理 5 int main() 6 { 7 int i,num; 8 scanf("%d",&num); 9 while(num--) 10 { 11 for(i=0;i<3;i++) 12 scanf("%s %s %s",left[i],right[i],result[i]); 13 for(i=0;i<12;i++) status[i]=0;//开始的时候,假设全部硬币都是真硬币。 14 for(i=0;i<12;i++) 15 { 16 status[i]=1;//假设第i枚硬币是假币且假币较重 17 if(Balanced())//检验该种假设是否合理 18 break; //若合理则已经得到答案,结束循环 19 20 status[i]=-1;//假设第i枚硬币是假币且假币较轻 21 if(Balanced())//检验该种假设是否合理 22 break; //若合理则已经得到答案,结束循环 23 24 status[i]=0;//上述两种假设都不合理的话,第i枚硬币为真硬币。 25 } 26 27 printf("%c is the counterfeit coin and it is %s. ",i+'A',status[i]==1?"heavy":"light"); 28 /**/ 29 } 30 31 return 0; 32 } 33 34 bool Balanced()//判断某种假设是否合理:合理则返回true,否则返回false. 35 { 36 int i,k,leftW,rightW; 37 for(i=0;i<3;i++)//依次检验三条规则 38 { 39 leftW=rightW=0; 40 for(k=0;left[i][k]!='