描述
Sally Jones 有十几个 Voyageur 银元。然而,只有 11 枚硬币是真正的银元;一枚硬币是伪造的,即使它的颜色和大小使其与真正的银元无法区分。假币与其他硬币的重量不同,但 Sally 不知道它比真币重还是轻。
幸运的是,莎莉有一个朋友借给她一个非常准确的天平秤。这位朋友将允许莎莉称重三下以找到假币。例如,如果 Sally 将两枚硬币相互称重并且天平保持平衡,那么她就知道这两枚硬币是真实的。现在如果莎莉重
一枚真硬币与第三枚硬币之间的天平不平衡,那么莎莉知道第三枚硬币是假币,她可以分别根据放置它的天平是上升还是下降来判断它是轻还是重。
通过仔细选择她的称量,Sally 能够确保她能找到恰好三个称量的假币。
幸运的是,莎莉有一个朋友借给她一个非常准确的天平秤。这位朋友将允许莎莉称重三下以找到假币。例如,如果 Sally 将两枚硬币相互称重并且天平保持平衡,那么她就知道这两枚硬币是真实的。现在如果莎莉重
一枚真硬币与第三枚硬币之间的天平不平衡,那么莎莉知道第三枚硬币是假币,她可以分别根据放置它的天平是上升还是下降来判断它是轻还是重。
通过仔细选择她的称量,Sally 能够确保她能找到恰好三个称量的假币。
输入
输入的第一行是一个整数 n (n > 0),指定要遵循的案例数。每个案例由三行输入组成,每个称重行。Sally 用字母 A--L 识别了每枚硬币。关于称重的信息将由两串字母给出,然后是单词“up”、“down”或“even”中的一个。第一串字母代表左边余额中的硬币;第二个字符串,硬币在正确的平衡。(Sally 将始终将相同数量的硬币放在右侧天平上和左侧天平上。)第三个位置的单词将说明天平的右侧是上升、下降还是保持平衡。
输出
对于每种情况,输出将通过字母识别假币并判断它是重还是轻。解决方案将始终是唯一确定的。
样本输入
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even
样本输出
K is the counterfeit coin and it is light.
解题思路
我们从十二枚硬币中依次假设,猜想它是轻的或者重的然后通过三次的称重结果判断是否成立,如果成立则说明我们的猜想正确,输出结果;如果不成立则继续猜下一枚硬币。
#include<iostream>
#include<cstring>
using namespace std;
bool IsFake(char c,bool light); //判断假设是否成立,成立返回true,不成立返回false
char Left[3][7]; //用于存储三次左侧存放的硬币
char Right[3][7]; //用于存储三次右侧存放的硬币
char Result[3][7]; //用于存储三次称量的结果
int main()
{
int n;
cin>>n;
while(n--){
for(int i=0;i<3;i++)
cin>>Left[i]>>Right[i]>>Result[i];
for(char c='A';c<='L';c++){
if(IsFake(c,true)) //假设c是假币且是轻的
{
cout<<c<<" is the counterfeit coin and it is light.\n";
}
else if(IsFake(c,false)) //假设c是假币且是重的
{
cout<<c<<" is the counterfeit coin and it is heavy.\n";
}
}
}
}
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]; //假设硬币重的情况,为了不再写一条switch所以将指针互换
pRight=Left[i];
}
switch(Result[i][0]){
case 'e':
if(strchr(pRight,c) || strchr(pLeft,c)) return false; //平衡,如果c在天平中则说明c不是假的
break;
case 'u':
if(strchr(pRight,c)==NULL) return false; //右侧轻,如果c在右侧说明假设成立,为空则c不在右侧假设错误
break;
case 'd':
if(strchr(pLeft,c)==NULL) return false; //右侧重,左侧轻,如果c在左侧说明假设成立,为空则c不在左侧假设错误
break;
}
}
return true;
}
成功AC,但还有更省事一点的,就是当出现平衡状态时,说明在称重的硬币都是真的,所以可以跳过这些硬币,不用遍历十二枚硬币来判断。代码就不给出了,大家可以自己去试试。
cjl