这个题大致思想就是用枚举的方法,从 A 到 L 枚举出所有可能的情况( A 为较轻的假币, A 为较重的假币,B 为较轻的假币......)。同时数据的读入也存在技巧,分别将每行三个字符串存放在三个二维字符数组中,这样每次只需一个 for 循环便可遍历所有的称量情况。还有一个巧妙的地方在于对“较轻”和“较重”两种猜测情况的处理,为了防止代码无意义的重复,可以在猜测某枚硬币较重时,令 *pLeft 指向右边的字符串, *pRight 指向左边的字符串,交换位置使得后面的 switch-case 代码可以重复利用。
代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
char Left[3][7], Right[3][7], result[3][5];
bool isFake(char c, bool light){
for(int i = 0; i < 3; i++){
char *pLeft, *pRight;
if(light){
pLeft = Left[i];
pRight = Right[i];
}else{
pLeft = Right[i];
pRight = Left[i];
}
switch(result[i][0]){
case 'u':
if(strchr(pRight, c) == NULL)
return false;
break;
case 'e':
if(strchr(pLeft, c) || strchr(pRight, c))
return false;
break;
case 'd':
if(strchr(pLeft, c) == NULL)
return false;
break;
}
}
return true;
}
int main()
{
int n;
scanf("%d", &n);
while(n--){
for(int i = 0; i < 3; i++)
cin >> Left[i] >> Right[i] >> result[i];
for(int c = 'A'; c <= 'L'; c++){
if(isFake(c, true)){
printf("%c is the counterfeit coin and it is light.\n", c);
break;
}
else if(isFake(c, false)){
printf("%c is the counterfeit coin and it is heavy.\n", c);
break;
}
}
}
return 0;
}