原题连接:poj-1013
题目大意:有12枚硬币,其中有且只有一枚假硬币,用A-L作为每个硬币的代号,假硬币可能略轻也可能略重,现根据三次天平称量的输入,来找出假硬币,并判断假硬币是略轻还是略重。
解题思路:通过模拟来解的,首先给所有的硬币重量赋值0,默认正常硬币的重量是10,若称量结果是even,则说明天平两边的硬币都是真硬币,则天平两边的硬币重量都赋值10;若结果是up,则说明左边比右边重,可能是左边有重的假硬币同时也有可能是右边有轻的假硬币,所以左右都应该被怀疑,所以左边非确定真硬币的硬币的重量应该+1,右边非确定真硬币的硬币的重量应该-1;若结果是light则进行相反的操作。最后结果即为非确定真硬币中被怀疑次数最多的硬币,即重量绝对值最大的硬币。
解释:因为每次判断除了even的情况都会怀疑两边,那么我们就可以找被怀疑程度最深的硬币,那么它一定就是假硬币。那么如何记录何判断怀疑程度呢?这里是通过上述的赋值来记录和判断的,若它在even的判断里边那么直接赋值10,不再参与后续赋值判断。若在重的一边则它被怀疑为重的假硬币则重量+1,若在轻的一边则它被怀疑为轻的假硬币则重量-1;因为若是真的硬币的话,他若被怀疑为重假硬币重量+1的话,后续他一定会在even的判断里或者再被怀疑为轻的假硬币重量-1,即它不可能一直与假硬币在一边,因为题意3次必出结果。所以我们就可以用最后重量的绝对值来衡量硬币的怀疑程度,并最后输出怀疑程度最高的硬币。
题目代码:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
char s1[13],s2[13],temp[10];
int flag[12];
memset(flag,0,sizeof(flag));
for(int i=0;i<3;i++)
{
scanf("%s%s%s",s1,s2,temp);
int len=strlen(s1);
if(strcmp(temp,"even")==0)
{
for(int j=0;j<len;j++)
{
flag[s1[i]-'A']=10;
flag[s2[i]-'A']=10;
}
}else if(strcmp(temp,"up")==0)
{
for(int j=0;j<len;j++)
{
if(flag[s1[j]-'A']!=10)
flag[s1[j]-'A']++;
if(flag[s2[j]-'A']!=10)
flag[s2[j]-'A']--;
}
}else
{
for(int j=0;j<len;j++)
{
if(flag[s1[j]-'A']!=10)
flag[s1[j]-'A']--;
if(flag[s2[j]-'A']!=10)
flag[s2[j]-'A']++;
}
}
}
int maxs=0,ans=0;
for(int i=0;i<12;i++)
{
if(flag[i]==10)
continue;
else if(maxs<=abs(flag[i]))
{
maxs=abs(flag[i]);
ans=i;
}
}
if(flag[ans]>0)
{
printf("%c is the counterfeit coin and it is heavy.\n",'A'+ans);
}else{
printf("%c is the counterfeit coin and it is light.\n",'A'+ans);
}
}
return 0;
}
若有不对/优化/不解,欢迎评论区留言/私信博主,博主有空一定会回答哒。
努力努力再努力x