欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenJ_Bailian-2692 假币问题(思维题)

程序员文章站 2022-05-13 17:15:02
...

Problem Description:

赛利有12枚银币。其中有11枚真币和1枚假币。假币看起来和真币没有区别,但是重量不同。但赛利不知道假币比真币轻还是重。于是他向朋友借了一架天平。朋友希望赛利称三次就能找出假币并且确定假币是轻是重。例如:如果赛利用天平称两枚硬币,发现天平平衡,说明两枚都是真的。如果赛利用一枚真币与另一枚银币比较,发现它比真币轻或重,说明它是假币。经过精心安排每次的称量,赛利保证在称三次后确定假币。

Input:

第一行有一个数字n,表示有n组测试用例。 
对于每组测试用例: 
输入有三行,每行表示一次称量的结果。赛利事先将银币标号为A-L。每次称量的结果用三个以空格隔开的字符串表示:天平左边放置的硬币 天平右边放置的硬币 平衡状态。其中平衡状态用``up'', ``down'', 或 ``even''表示, 分别为右端高、右端低和平衡。天平左右的硬币数总是相等的。

Output:

输出哪一个标号的银币是假币,并说明它比真币轻还是重(heavy or light)。

Sample Input:

1
ABCD EFGH even 
ABCI EFJK up 
ABIJ EFGH even

Sample Output:

K is the counterfeit coin and it is light.

思路:

开一个数组(下面代码中的dp数组)表示每个银币的状态,共有4中状态,分别用4个整数表示,未知状态用0表示,真币用2表示,轻的假币用-1表示,重的假币用1表示。先将所有银币的状态都初始化为0,若两边相等的则两边的硬币都为真币,将两边银币的状态都置为2;如两边不等则两边必有一边存在假币,将轻的那边状态还是未知的银币的状态置为-1,将重的那边状态还是未知的银币的状态置为1。判断银币为真币的情况有两种:一种是两边相等的情况;另一种是某个银币之前在轻的那边后来在重的那边,或者之前在重的那边后来在轻的那边,这样的银币也可以确定为真币。最后状态为-1的输出并表明假币是轻的,状态为1的输出并表明假币是重的。

上AC代码:

#include <stdio.h>
#include <string.h>
int t;
char a[7],b[7],res[5];
int dp[12];
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        int i,j;
        memset(dp,0,sizeof(dp));
        for(i=1;i<=3;i++)
        {
            scanf("%s %s %s",a,b,res);
            int len1=strlen(a);
            int len2=strlen(b);
            if(res[0]=='e')
            {
                for(j=0;j<len1;j++)
                {
                    dp[a[j]-'A']=2;
                }
                for(j=0;j<len2;j++)
                {
                    dp[b[j]-'A']=2;
                }
            }
            else if(res[0]=='u')
            {
                for(j=0;j<len1;j++)
                {
                    if(dp[a[j]-'A']!=2)
                    {
                        if(dp[a[j]-'A']==-1)
                        {
                            dp[a[j]-'A']=2;
                        }
                        else
                        {
                            dp[a[j]-'A']=1;
                        }
                    }
                }
                for(j=0;j<len2;j++)
                {
                    if(dp[b[j]-'A']!=2)
                    {
                        if(dp[b[j]-'A']==1)
                        {
                            dp[b[j]-'A']=2;
                        }
                        else
                        {
                            dp[b[j]-'A']=-1;
                        }
                    }
                }
            }
            else
            {
                for(j=0;j<len1;j++)
                {
                    if(dp[a[j]-'A']!=2)
                    {
                        if(dp[a[j]-'A']==1)
                        {
                            dp[a[j]-'A']=2;
                        }
                        else
                        {
                            dp[a[j]-'A']=-1;
                        }
                    }
                }
                for(j=0;j<len2;j++)
                {
                    if(dp[b[j]-'A']!=2)
                    {
                        if(dp[b[j]-'A']==-1)
                        {
                            dp[b[j]-'A']=2;
                        }
                        else
                        {
                            dp[b[j]-'A']=1;
                        }
                    }
                }
            }
        }
        for(i=0;i<12;i++)
        {
            if(dp[i]!=2&&dp[i]!=0)
            {
                if(dp[i]==-1)
                {
                    printf("%c is the counterfeit coin and it is light.\n",'A'+i);
                }
                else
                {
                    printf("%c is the counterfeit coin and it is heavy.\n",'A'+i);
                }
                break;
            }
        }
    }
    return 0;
}