思路:对于每一枚硬币首先假设它是轻的,看这样是否符合称量结果。如果符合,问题即解决,如果不符合,就假设他是重的,看是否符合称量结果,把所有硬币都试一遍,一定能找到特殊硬币。
参考代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char Left[3][7]; //天平左边硬币
char Right[3][7]; //天平右边硬币
char result[3][7]; //结果
bool IsFake(char c, bool light);
//light为真表示假设硬币为轻,否则表示假设硬币为重
int main()
{
int t;
cin >> t;
while(t--)
{
for(int i=0; i<3; i++)
{
cin >> Left[i] >> Right[i] >> result[i]; //读入3组数据
}
//枚举所有的情况
for(char c='A'; c<='L'; c++)
{
if(IsFake(c, true)) //待判断的字符c是light的
{
cout << c << " is the counterfeit coin and it is light." << endl;
break; //找到之后直接退出
}
else if(IsFake(c, false))
{
cout << c << " is the counterfeit coin and it is heavy." << endl;
break;
}
}
}
return 0;
}
bool IsFake(char c, bool light)
{
//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': //对应up
if(strchr(pRight, c) == NULL)
return false;
break;
case 'e': //对应even
if(strchr(pLeft, c) || strchr(pRight, c))
return false;
break;
case 'd': //对应down
if(strchr(pLeft, c) == NULL)
return false;
break;
}
}
return true;
}