zoukankan      html  css  js  c++  java
  • [LeetCode]52. Bulls and Cows猜数字游戏

    You are playing the following Bulls and Cows game with your friend: You write a 4-digit secret number and ask your friend to guess it. Each time your friend guesses a number, you give a hint. The hint tells your friend how many digits are in the correct positions (called "bulls") and how many digits are in the wrong positions (called "cows"). Your friend will use those hints to find out the secret number.

    For example:

    Secret number:  "1807"
    Friend's guess: "7810"
    

    Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.)

    Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows. In the above example, your function should return "1A3B".

    Please note that both secret number and friend's guess may contain duplicate digits, for example:

    Secret number:  "1123"
    Friend's guess: "0111"
    

    In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B".

    You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal.

    Credits:
    Special thanks to @jeantimex for adding this problem and creating all test cases.

    Subscribe to see which companies asked this question

    解法:有一个四位数字,你猜一个结果,然后根据你猜的结果和真实结果做对比,提示有多少个数字和位置都正确的叫做bulls,还提示有多少数字正确但位置不对的叫做cows。因此我们首先统计猜对了几个数字,然后统计有几个猜对的数字在正确的位置上。

    class Solution {
    public:
        string getHint(string secret, string guess) {
            int n = secret.size(), bulls = 0, total = 0;
            vector<int> sv(10, 0), gv(10, 0);
            for(int i = 0; i < n; ++i)
            {
                ++sv[secret[i] - '0'];
                ++gv[guess[i] - '0'];
            }
            for(int i = 0; i < 10; ++i)
                total += min(sv[i], gv[i]);
    
            for(int i = 0; i < n; ++i)
                if(secret[i] == guess[i]) ++bulls;
    return to_string(bulls) + 'A' + to_string(total - bulls) + 'B'; } };

    上面的解法可以简化:首先在一次循环中找出所有bulls,即数字与位置均正确的个数,同时在这个过程中可以记录下非bulls时secret的分布情况;然后在第二次循环中就可以根据secret的分布情况统计cows的个数了。

    class Solution {
    public:
        string getHint(string secret, string guess) {
            int n = secret.size(), bulls = 0, cows = 0;
            vector<int> v(10, 0);
            for(int i = 0; i < n; ++i)
            {
                if(guess[i] == secret[i]) ++bulls;
                else ++v[secret[i] - '0']; //注意只在非bulls时才记录
            }
            for(int i = 0; i < n; ++i)
            {
                if(guess[i] != secret[i] && v[guess[i] - '0'] != 0)
                {
                    ++cows;
                    --v[guess[i] - '0'];
                }
            }
            return to_string(bulls) + "A" + to_string(cows) + "B";
        }
    };

    再精简,使用一次循环解决。在处理不是bulls的位置时,如果secret当前位置数字的映射值小于0,则表示其在guess中出现过,cows自增1,然后映射值加1,如果guess当前位置的数字的映射值大于0,则表示其在secret中出现过,cows自增1,然后映射值减1。

    class Solution {
    public:
        string getHint(string secret, string guess) {
            int n = secret.size(), bulls = 0, cows = 0;
            vector<int> v(10, 0);
            for(int i = 0; i < n; ++i)
            {
                if(guess[i] == secret[i]) ++bulls;
                else
                {
                    if(v[guess[i] - '0']-- > 0) ++cows;
                    if(v[secret[i] - '0']++ < 0) ++cows;
                }
            }
            return to_string(bulls) + "A" + to_string(cows) + "B";
        }
    };

    参考:http://www.cnblogs.com/grandyang/p/4929139.html

  • 相关阅读:
    【洛谷5304】[GXOI/ZOI2019] 旅行者(二进制分组+最短路)
    【LOJ6485】LJJ 学二项式定理(单位根反演)
    【CF932E】Team Work(第二类斯特林数简单题)
    【CF960G】Bandit Blues(第一类斯特林数)
    【洛谷4689】[Ynoi2016] 这是我自己的发明(莫队)
    【洛谷5355】[Ynoi2017] 由乃的玉米田(莫队+bitset)
    【洛谷5268】[SNOI2017] 一个简单的询问(莫队)
    【洛谷4688】[Ynoi2016] 掉进兔子洞(莫队+bitset)
    【洛谷3653】小清新数学题(数论)
    【洛谷6626】[省选联考 2020 B 卷] 消息传递(点分治基础题)
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/4929939.html
Copyright © 2011-2022 走看看