/*
题意:
有一打(12枚)硬币,其中有且仅有1枚假币,11枚真币
用A~L作为各个硬币的代号
假币可能比真币略轻,也可能略重
现在利用天枰(称时两边数目相同),
根据Input输入的3次称量,找出假币,
并输出假币是轻还是重。
算法:推理:
当出现even时,天枰两边的硬币必然都为真币,
那么我们就可以定义一个标记数组 zero[]去标记even时的真币,
处理up和down状态方法:
当出现up或down状态时,天枰两边的所有硬币都应该被怀疑为假币
(已标记必定为真币的硬币不必被怀疑)。
首先judge[]记录每个硬币的被怀疑程度,judge[i]=0表示该硬币i
不被怀疑(即其可能为真币)。
在up状态盘的硬币为“轻”,
通过“-1”操作加深其被怀疑为轻假币的程度,
在down状态盘的硬币为“重”,
通过“+1”操作加深其被怀疑为重假币的程度,
那么若一枚真币被怀疑为“轻”时,
它就可能通过下次称量通过“+1”操作取消嫌疑了。
初始化所有硬币的怀疑程度均为0。
称量完毕后,找出被怀疑程度最大(注意取绝对值)的硬币,
它就是假币。而当其怀疑方向为正时,则其为重假币。为负时,为轻假币。
#include <cstring>
#include <cmath>
using namespace std;
int main()
{
int i,ans,n;
string left,right,status;
int judge[15];
bool zero[15];
cin>>n;
for (i=1;i<=n;i++)
{
memset(judge,0,sizeof(judge));
memset(zero,false,sizeof(zero));
for (int j=1;j<=3;j++)
{
cin>>left;
cin>>right;
cin>>status;
int length;
length=left.length();//每次称的数量不一定相同
if (status=="even")
for (int k=0;k<=length;k++)
{
zero[left[k]-'A'+1]=true;
zero[right[k]-'A'+1]=true;
}
else if (status=="up")
for (int k=0;k<=length;k++)
{
if (zero[left[k]-'A'+1]==false)
judge[left[k]-'A'+1]+=1;
if (zero[right[k]-'A'+1]==false)
judge[right[k]-'A'+1]-=1;
}
else
for (int k=0;k<=length;k++)
{
if (zero[left[k]-'A'+1]==false)
judge[left[k]-'A'+1]-=1;
if (zero[right[k]-'A'+1]==false)
judge[right[k]-'A'+1]+=1;
}
}
for (int k=1;k<=12;k++)
if (zero[k]==true) judge[k]=0;
ans=1;
for (int k=2;k<=12;k++)
if (judge[k]*judge[k]>judge[ans]*judge[ans]) ans=k;
cout<<char('A'+ans-1)<<" is the counterfeit coin and it is ";
if (judge[ans]<0) cout<<"light."<<endl;
if (judge[ans]>0) cout<<"heavy."<<endl;
}
return 0;
}
题意:
有一打(12枚)硬币,其中有且仅有1枚假币,11枚真币
用A~L作为各个硬币的代号
假币可能比真币略轻,也可能略重
现在利用天枰(称时两边数目相同),
根据Input输入的3次称量,找出假币,
并输出假币是轻还是重。
算法:推理:
当出现even时,天枰两边的硬币必然都为真币,
那么我们就可以定义一个标记数组 zero[]去标记even时的真币,
处理up和down状态方法:
当出现up或down状态时,天枰两边的所有硬币都应该被怀疑为假币
(已标记必定为真币的硬币不必被怀疑)。
首先judge[]记录每个硬币的被怀疑程度,judge[i]=0表示该硬币i
不被怀疑(即其可能为真币)。
在up状态盘的硬币为“轻”,
通过“-1”操作加深其被怀疑为轻假币的程度,
在down状态盘的硬币为“重”,
通过“+1”操作加深其被怀疑为重假币的程度,
那么若一枚真币被怀疑为“轻”时,
它就可能通过下次称量通过“+1”操作取消嫌疑了。
初始化所有硬币的怀疑程度均为0。
称量完毕后,找出被怀疑程度最大(注意取绝对值)的硬币,
它就是假币。而当其怀疑方向为正时,则其为重假币。为负时,为轻假币。
*/
#include <iostream>
#include <cstdio>#include <cstring>
#include <cmath>
using namespace std;
int main()
{
int i,ans,n;
string left,right,status;
int judge[15];
bool zero[15];
cin>>n;
for (i=1;i<=n;i++)
{
memset(judge,0,sizeof(judge));
memset(zero,false,sizeof(zero));
for (int j=1;j<=3;j++)
{
cin>>left;
cin>>right;
cin>>status;
int length;
length=left.length();//每次称的数量不一定相同
if (status=="even")
for (int k=0;k<=length;k++)
{
zero[left[k]-'A'+1]=true;
zero[right[k]-'A'+1]=true;
}
else if (status=="up")
for (int k=0;k<=length;k++)
{
if (zero[left[k]-'A'+1]==false)
judge[left[k]-'A'+1]+=1;
if (zero[right[k]-'A'+1]==false)
judge[right[k]-'A'+1]-=1;
}
else
for (int k=0;k<=length;k++)
{
if (zero[left[k]-'A'+1]==false)
judge[left[k]-'A'+1]-=1;
if (zero[right[k]-'A'+1]==false)
judge[right[k]-'A'+1]+=1;
}
}
for (int k=1;k<=12;k++)
if (zero[k]==true) judge[k]=0;
ans=1;
for (int k=2;k<=12;k++)
if (judge[k]*judge[k]>judge[ans]*judge[ans]) ans=k;
cout<<char('A'+ans-1)<<" is the counterfeit coin and it is ";
if (judge[ans]<0) cout<<"light."<<endl;
if (judge[ans]>0) cout<<"heavy."<<endl;
}
return 0;
}