这个是经典的枚举问题,一开始的思路是从A-L遍历硬币,如果找到一个硬币满足三个条件就判定这个硬币是假的,就输出
但是这种思路存在的BUG是,如果三个式子中这个硬币没有出现,或者硬币只在1-2个式子中出现并且符合假设,这样会导致出新的问题,所以根据大佬的提醒以后,修改为改变硬币的价值,如果是假的轻硬币就设置为-1,如果是假的重硬币就设置为1,这样每次加出天平左右两边硬币的价值,之后判断满足条件问题(自己叫做称重法)
这个题还有一个比较坑的就是两边硬币数目一定相等但不一定都是四个,可以是33,22……一开始虽然算法不对不过也是被这块坑了比较久,一开始用的是模拟的输入方法,后来经过大佬提醒还是改成了每次输入三个字符串
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <cstring>
#include <cmath>
#include <cstdlib>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int main(int argc, char** argv) {
int n;
scanf("%d",&n);
while(n--)//省去了一个变量
{
char a[3][100];//储存左边天平的n个字母
char b[3][100];//储存右边天平的n个字母
char c[3][100];//储存状态
int left = 0;
int right = 0;
for(int i=0;i<3;i++)
{
scanf("%s%s%s",a[i],b[i],c[i]); //输入部分没有问题
}
int judge = 0;
for(int w=-1;w<2;w++)
{
int val[1005]={0};
if(w==0) continue;
for(int i='A';i<='L';i++)
{
val[i] = w;//A 是 轻的假币 并且保证了其他都是好的
for(int l=0;l<3;l++)
{
left = 0;
right = 0;
for(int j=0;j<strlen(a[l]);j++)
{
left += val[a[l][j]]; //角标是什么
}
for(int j=0;j<strlen(b[l]);j++)
{
right += val[b[l][j]];
}
// printf("left = %d\t,right = %d\n",left,right);
if((left<right&&c[l][0]!='u')||(left>right&&c[l][0]!='d')||(left==right&&c[l][0]!='e'))
{
goto out;
}
}
if(w<0)
{
printf("%c is the counterfeit coin and it is heavy.\n",i);
}
if(w>0)
{
printf("%c is the counterfeit coin and it is light.\n",i);
}
out:
val[i] = 0;
}
}
}
//system("pause");
return 0;
}