解题思路参照他人,大概为每一枚硬币有两个元素,一为是否为真币,一为被怀疑为假币的程度。初始全为假币,且怀疑程度为0。当两边相等时则可确定为真币,当不相等时轻的一边怀疑程度减一,重的这边怀疑程度加一,当最后未被确定为真币且怀疑程度最大的则为假币,再根据其怀疑程度的正负判断是轻了还是重了。
#include<iostream>
using namespace std;
typedef struct coin
{
int degree;
bool bl;
}coin;//结构体存硬币的两个元素
void lessen(coin c[],int n,string s)//怀疑程度--
{
for(int i=0;i<n;i++)
{
int a=int(s[i])-65;//字母转为int比其结构体数组位置多65
c[a].degree--;
}
}
void increase(coin c[],int n,string s)//怀疑程度++
{
for(int i=0;i<n;i++)
{
int a=int(s[i])-65;
c[a].degree++;
}
}
int main(void)
{
string s1,s2,s3;
int cases;
int max;
cin>>cases;
while(cases)
{
coin c[13];
for(int i=0;i<13;i++)
{
c[i].degree=0;
c[i].bl=false;
}//初始化全为假币且怀疑程度为0
max=12;
for(int i=0;i<3;i++)//三次称量
{
cin>>s1>>s2>>s3;
if(s3=="up")
{
increase(c,s1.size(),s1);
lessen(c,s2.size(),s2);
}
else if(s3=="even")
{
for(int i=0;i<s1.size();i++)
{
int a=int(s1[i])-65;
int b=int(s2[i])-65;
c[a].bl=true;
c[b].bl=true;
}
}
else
{
lessen(c,s1.size(),s1);
increase(c,s2.size(),s2);
}
}
for(int i=0;i<12;i++)
{
if(c[i].degree*c[i].degree>c[max].degree*c[max].degree&&!c[i].bl)
max=i;
}
if(c[max].degree<0) cout<<char(max+65)<<" is the counterfeit coin and it is light."<<endl;
else cout<<char(max+65)<<" is the counterfeit coin and it is heavy."<<endl;
cases--;
}
return 0;
}