有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
这题思路比较简单 就是暴力,枚举法下面配合着代码 详细说下思路。
先假设 c是假币 并且他是轻的
#include <iostream>
#include <cstring>
using namespace std;
char Left[3][7];
char Right[3][7];
char result[3][7];
bool IsFake(char c,bool light);//c是假币 并且为轻
int main()
{
int t;
cin>>t;
while(t--)
{
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)) //进入函数
{
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)//lingh为真表示假币为轻,否则假币为重 先假设为轻
{
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; //不在右边 则与 天平右边上升相违背 返回false 并且你的假设(c是轻的硬币是错误的)
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;
}
详细的讲解可以看郭炜老师的讲解 很精细!!
https://www.icourse163.org/learn/PKU-1001894005?tid=1463180448#/learn/content?type=detail&id=1240390166