Counterfeit Dollar 题解

题目

题目链接

Counterfeit Dollar

题目大意

这道题啊,他讲的是,一个人,名字叫Sally,他有12个钢镚,其中有1个是假的,假的这个钢镚除了重量和真的不一样,其他的一毛一样。
现在她拿天平称了3次,就知道哪个是假的了,要求你写个程序来判断哪个是假的,并且假的这个是轻还是重。

输入

第一行包含一个正整数n,表示测试情况数量。

之后每个测试情况共3行,每行由3个字符串组成。

第1个字符串表示天平左边的硬币,第2个字符串表示天平右边的硬币,第3个字符串表示右边的秤盘是上去了还是下去了,还是一动不动(up, down, even)。

输出

对于每个测试情况,找出假的那个硬币,并说明假的这个是轻还是重(light, heavy)。

样例输入

1
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even

样例输出

K is the counterfeit coin and it is light.

题解

我们可以从第1个硬币开始假设为假硬币,是轻,然后套入3次称量结果中比对。

如果不对,那就再假设是重,再套入3次称量结果中比对。

如果不对,那就假设第2个硬币,依次下去直到假设的结果与称量结果符合。

以上是主体的思路,还可以考虑一些细节,减少枚举的情况数量。比如天平称量结果为even,那么称量的这些硬币肯定都是真币。

另外题目中没有说每次称量多少个硬币哦。

文章最后有额外测试数据。

Then show the code.

#include <cstdio>
#include <cstring>

//bl是左边秤盘 br为右边秤盘 be为称量结果
char bl[3][10], br[3][10], be[3][5];
//s表示每个硬币是否排除了假币的嫌疑
char s[12], so[2][6];

// hea=0为轻 
bool judge(char c, int hea){
    //假设c为轻
    if(!hea){
        for(int i=0; i<3; i++){
            int flag = 1;
            int len = strlen(bl[i]);
            for(int j=0; j<len && flag; j++){
                if(bl[i][j] == c){
                    flag = 0;
                    if(be[i][0] != 'd') 
                        return false;
                }
                if(br[i][j] == c){
                    flag = 0;
                    if(be[i][0] != 'u')
                        return false;
                }
            }
            if(flag){
                if(be[i][0] != 'e')
                    return false;
            }
        }
    //假设c为重
    }else{
        for(int i=0; i<3; i++){
            int flag = 1;
            int len = strlen(bl[i]);
            for(int j=0; j<len && flag; j++){
                if(bl[i][j] == c){
                    flag = 0;
                    if(be[i][0] != 'u') 
                        return false;
                }
                if(br[i][j] == c){
                    flag = 0;
                    if(be[i][0] != 'd')
                        return false;
                }
            }
            if(flag){
                if(be[i][0] != 'e')
                    return false;
            }
        }
    }
    
    return true;
}

int main(){
    int t;
    scanf("%d", &t);
    strcpy(so[0], "light");
    strcpy(so[1], "heavy");
    while(t--){
        memset(s, 1, sizeof(s));
        for(int i=0; i<3; i++){
            scanf("%s%s%s", &bl[i], &br[i], &be[i]);
            //减少枚举情况数量
            if(be[i][0] == 'e'){
                int len = strlen(bl[i]);
                for(int j=0; j<len; j++){
                    s[bl[i][j]-'A'] = 0;
                    s[br[i][j]-'A'] = 0;
                }
            }
        }
        int flag = 0;
        for(int i=0; i<12; i++){
            if(flag) break;
            if(!s[i]) continue;
            for(int j=0; j<=1; j++){
                if(judge(i+'A', j)){
                    printf("%c is the counterfeit coin and it is %s.\n", i+'A', so[j]);
                    flag = 1;
                }
            }
            
        }
        
    }
    return 0;
}

测试数据来自浅忆的此博文

输入

12
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even
AGHL BDEC even
JKI ADE up
J K even
ABCDEF GHIJKL up
ABC DEF even
I J down
ABCDEF GHIJKL up
ABHLEF GDIJKC down
CD HA even
A B up
B A down
A C even
A B up
B C even
DEFG HIJL even
ABC DEJ down
ACH IEF down
AHK IDJ down
ABCD EFGH even
AB IJ even
A L down
EFA BGH down
EFC GHD even
BA EF down
A B up
A C up
L K even
ACEGIK BDFHJL up
ACEGIL BDFHJK down
ACEGLK BDFHJI down
ACEGIK BDFHJL up
ACEGIL BDFHJK down
ACEGLK BDFHJI up

输出

K is the counterfeit coin and it is light.
I is the counterfeit coin and it is heavy.
I is the counterfeit coin and it is light.
L is the counterfeit coin and it is light.
B is the counterfeit coin and it is light.
A is the counterfeit coin and it is heavy.
A is the counterfeit coin and it is light.
L is the counterfeit coin and it is heavy.
A is the counterfeit coin and it is light.
A is the counterfeit coin and it is heavy.
L is the counterfeit coin and it is light.
K is the counterfeit coin and it is heavy.
posted @ 2020-12-14 12:49  1v7w  阅读(329)  评论(0编辑  收藏  举报