题意:有12枚硬币,其中有一枚假币,假币可以轻也可能重,试着通过3次称量找出那枚假币并说明它是重的还是轻的
思路:算是水题吧,通过对一些小例子进行简单的逻辑推理,
AB DE up
AC FE up
BE HJ even
可以得到4点结论:(这里可知A是重的假硬币)
1.如果左右两边是even的,说明左右两边的硬币肯定都是真的。所以BEHJ的嫌疑都排除了
2.含有A的那一边总是重
3.B,C和A放在一起时也会显示出“重”,但是A重的次数肯定是最多的,同时A肯定没满足过even的情况。
4.可能有A的一边“重”的情况出现的2次,有“D”的一边轻的情况出现了1次,那么肯定A是假的。因为2>1.
于是就明白如何表示了,用v[ ] 数组表示是否出现过even的情况,用a[ ]数组表示轻重的次数,轻就--,重就++,用绝对值表示次数,肯定是绝对值最大的为假币
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int a[12],v[12];
char l[12],r[12],state[5];
int main()
{
int n,t,i,j,m,len;
cin>>t;
while(t--)
{
memset(a,0,sizeof(a));
memset(v,0,sizeof(v));
for(i=1;i<=3;i++)
{
scanf("%s%s",l,r);
n=strlen(l);
scanf("%s",state);
if(strcmp(state,"even")==0) //如果相等,说明肯定不是假币,v值赋值为1
{
for(j=0;j<n;j++)
{
v[l[j]-'A']=1;
v[r[j]-'A']=1;
}
}
else if(strcmp(state,"up")==0) //如果左边比右边重,则左边的a值都+1,右边的a值都减1
{
for(j=0;j<n;j++)
{
a[l[j]-'A']++;
a[r[j]-'A']--;
}
}
else
for(j=0;j<n;j++) //左边比右边轻,同理
{
a[l[j]-'A']--;
a[r[j]-'A']++;
}
}
int max=0;
for(j=0;j<12;j++)
if(v[j]!=1&&abs(a[j])>max) //如果没出现过相等的情况而且a值的绝对值最大,认定为假币
{
max=abs(a[j]);
m=j;
}
if(a[m]<0)
printf("%c is the counterfeit coin and it is light.\n",m+'A');
else printf("%c is the counterfeit coin and it is heavy.\n",m+'A');
}
}