• OpenJudge NOI 2.1 15:Counterfeit Dollar


    【题目链接】

    OpenJudge NOI 2.1 15:Counterfeit Dollar

    【题目考点】

    1. 枚举

    【题目翻译】

    题目

    假币

    描述

    莎莉琼斯有12枚航记银元,但是,只有其中的11个是真正的银元,有1枚是伪造的假币,尽管它的颜色和形状大小让它无法与真正的银元区分开来。这个假币与其他硬币的重量不同,但莎莉不知道它与其他硬币相比是更重还是更轻。

    幸运的是,莎莉有一个朋友借给了她一个十分精确的天平,这个朋友给了莎莉三次称重的机会来找出那个假币。例如,如果莎莉称两枚硬币且天平平衡,那么她就知道这两枚硬币是真的。现在,如果莎莉将其中一枚真硬币与第三个硬币称重,天平不平衡,那么她就知道第三枚硬币是假币,并且她还能通过天平哪边向上、向下移动来判断那个假币是轻还是重。
    通过仔细选择如何称重,莎莉可以保证,她只需要3次称重就可以找到那枚假币。

    输入

    第一行输入是一个整数n (n>0) 指明有几组测试数据,每组数据由三行输入组成,一行代表一次称重。莎莉用字母A到L标记了所有硬币。每次称重的信息都包括两个字母字符串,与“up”、“down”、“even”三个单词中的一个词。第一个字母字符串表示天平左盘的硬币,第二个字母字符串则是天平右盘的硬币(莎莉总是在天平的左右两盘分别放入相同数量的银元)。第三个位置的单词是表明天平的右边是会向上移动、向下移动,还是保持平衡。

    输出

    对于每组数据,输出字母来表明哪一个是假币,并判断它是更重还是更轻。解决方案始终唯一确定。
    这句话第一个字母为假币对应的字母,最后一个单词为:light(更轻)或heavy(更重)。

    来源

    East Central North America 1998

    【解题思路】

    一共有A–L共十二枚硬币,其中一枚假币,假币可能更轻或更重。
    所以可能的情况有:
    0更轻,0更重,1更轻,1更重,…,11更轻,11更重。一共24种情况。
    枚举这24种情况,看哪种情况下,输入指定的三次天平比较结果与实际的结果相同。

    假设输入为:ABCI EFJK up
    如果我假设A是更轻的假币,那么右端应该下沉,实际的结果是右端上翘,与实际结果不同。
    如果我假设A是更重的假币,那么右端应该上翘,与实际结果相同。

    如果在当前假币情况下,输入指定的三次天平比较的结果与实际结果都相同,那么此时假币的情况就是真实的,可行的。否则该假币情况不可行。

    【题解代码】

    解法1:

    • C风格
    #include<bits/stdc++.h>
    using namespace std;
    #define N 15
    bool hasCh(char s[], char c)//字符串s中是否包含字符c 
    {
        int len = strlen(s);
        for(int i = 0; i < len; ++i)
            if(s[i] == c)
                return true;
        return false;
    }
    void check(bool ishev, bool hl, bool hr, char res[])//ishev表示假币是否更重,hl表示左侧是否有假币 ,hr表示右侧是否有假币,res保存结果字符串
    {
        if(!hl && !hr)
            strcpy(res, "even");
        else if(!ishev && !hl && hr || ishev && hl && !hr)//更轻的在右边,或更重的在左边 
            strcpy(res, "up");
        else if(!ishev && hl && !hr || ishev && !hl && hr)//更轻的在左边,或更重的在右边 
            strcpy(res, "down");
    }
    int main()
    {
        char s[4][4][N], lh[2][N] = {"light", "heavy"}, res[N];//输入的字符串 
        int n;
        scanf("%d", &n);
        bool isMatch, isHeavy;
        while(n--)
        {
            for(int i = 1; i <= 3; ++i)
                scanf("%s %s %s", s[i][1], s[i][2], s[i][3]);
            for(char c = 'A'; c <= 'L'; ++c)//假设假币为c 
            {
                for(int k = 0; k < 2; ++k)//假设假币为lh[k],可能的值为light更轻,或heavy更重 
                {
                    isMatch = true, isHeavy = strcmp(lh[k], "heavy") == 0; 
                    for(int j = 1; j <= 3; ++j)//看比较规则j 
                    {
                        bool hl = hasCh(s[j][1], c), hr = hasCh(s[j][2], c);
                        check(isHeavy, hl, hr, res);
                        if(strcmp(res, s[j][3]) != 0)//如果当前假币情况得到的结果与预设结果不同 
                        {
                            isMatch = false;
                            break;
                        }
                    }
                    if(isMatch)
                    {
                        printf("%c is the counterfeit coin and it is %s.\n", c, lh[k]);
                        break;
                    }
                }
                if(isMatch)
                    break;
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • C++风格
    #include<bits/stdc++.h>
    using namespace std;
    bool hasCh(string s, char c)//判断s中是否有c 
    {
        for(int i = 0; i < s.length(); ++i)
            if(s[i] == c)
                return true;
        return false;
    }
    string getRes(char f, string lh, string s1, string s2)//f是假币,lh:字符串 表示更重或更轻,天平两边是s1,s2,看能得到什么结果 
    {
        bool h1 = hasCh(s1, f), h2 = hasCh(s2, f);//h1:s1中是否有f,h2:s2中是否有f
        if(h1 == false && h2 == false)
            return "even";
        else if(h1 == true && h2 == false)
        {
            if(lh == "heavy")
                return "up";
            else
                return "down";
        }
        else if(h1 == false && h2 == true)
        {
            if(lh == "heavy")
                return "down";
            else
                return "up";
        }
    }
    int main()
    {
        bool isMatch;
        int n;
        cin >> n;
        string s[4][4];
        string lh[2] = {"light", "heavy"};
        while(n--)
        {
            for(int i = 1; i <= 3; ++i)
                for(int j = 1; j <= 3; ++j) 
                    cin >> s[i][j];
            for(char c = 'A'; c <= 'L'; ++c)//假设假币为c 
            {
                for(int k = 0; k < 2; ++k)//假设假币为lh[k],可能的值为light更轻,或heavy更重 
                {
                    isMatch = true;//当前假币情况是否可以让3次天平的结果都是预设结果。 
                    for(int i = 1; i <= 3; ++i)
                    {
                        if(getRes(c, lh[k], s[i][1], s[i][2]) != s[i][3])//如果当前假币情况得到的结果与预设结果不同 
                        { 
                            isMatch = false;            
                            break;
                        }
                    }
                    if(isMatch)
                    {
                        cout << c << " is the counterfeit coin and it is " << lh[k] << '.' << endl;
                        break;
                    }
                }
                if(isMatch)//如果找到合适的假币,则跳出 
                    break;
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
  • 相关阅读:
    C++语法——详细剖析多态与虚函数
    R语言ggplot2可视化:使用ggpubr包的ggbarplot函数可视化柱状图、不同水平的柱状图中包含多个数据对象(每个横线代表一个数据对象)
    【CGAL_网格处理】坐标变换
    Matlab中函数参数验证
    【SpringBoot】SpringBoot 读取配置文件中的自定义属性的 5 种方法
    ruby ftp封装实例详解
    【React】第七部分 Dom的diffing算法
    C# .NET CORE .NET6 RSA 公钥加密 私钥解密
    黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录 Day4
    C++程序调试详解(包括打断点 单步调试 数据断点...)
  • 原文地址:https://blog.csdn.net/lq1990717/article/details/125462573