搜索专题-Counterfeit Dollar

原题连接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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值