猜数字

题目描述

一个人设定一组四码的数字作为谜底,另一方猜。

每猜一个数,出数者就要根据这个数字给出提示,提示以XAYB形式呈现,直到猜中位置。

其中X表示位置正确的数的个数(数字正确且位置正确),而Y表示数字正确而位置不对的数的个数。

例如,当谜底为8123,而猜谜者猜1052时,出题者必须提示0A2B。

例如,当谜底为5637,而猜谜者才4931时,出题者必须提示1A0B。

当前已知N组猜谜者猜的数字与提示,如果答案确定,请输出答案,不确定则输出NA。

输入描述

第一行输入一个正整数,0<N < 100。

接下来N行,每一行包含一个猜测的数字与提示结果。

输出描述

输出最后的答案,答案不确定则输出NA。

示例1

输入:
6
4815 1A1B
5716 0A1B
7842 0A1B
4901 0A0B
8585 3A0B
8555 2A1B

输出:
3585

题解

这道题属于 暴力搜索(Brute Force) 结合 模拟(Simulation) 的算法题。我们需要枚举所有可能的4位数,并验证每个数是否符合给定的所有提示条件。

解题思路

  1. 输入处理:读取输入的猜测记录(数字和对应的XAYB提示)。
  2. 验证函数:编写一个 check 函数,判断某个候选答案是否符合某条猜测记录的提示。
  • 计算数字和位置都正确的数量(X)。
  • 计算数字正确但位置不对的数量(Y)。
  1. 枚举所有可能的4位数:从 00009999,检查每个数是否满足所有给定的提示记录。
  2. 输出结果:如果只有一个候选答案满足所有条件,输出它;否则输出 NA

C++

#include <bits/stdc++.h>

using namespace std;

bool check(const string& guess, const string& answer, const string& expectResult) {
    // 数字正确且位置正确个数
    int x = 0;
    for (int i = 0; i < 4; i++) {
        if (guess[i] == answer[i]) x++;
    }

    // 数字正确而位置不对的数的个数
    map<char, int> cnt1, cnt2;
    for (char c : guess) cnt1[c]++;
    for (char c : answer) cnt2[c]++;
    int y = 0;
    for (const auto& [k, v] : cnt1) {
        y += min(v, cnt2[k]);;
    }
    y -= x;

    string actualResult = to_string(x) + "A" + to_string(y) + "B";
    return actualResult == expectResult;
}

int main() {
    int n;
    cin >> n;
    cin.ignore();  // 忽略换行符

    vector<pair<string, string>> logs;
    for (int i = 0; i < n; i++) {
        string guess, result;
        cin >> guess >> result;
        logs.emplace_back(guess, result);
    }

    vector<string> candidates;
    for (int x = 0; x < 10000; x++) {
        stringstream ss;
        ss << setw(4) << setfill('0') << x;
        string answer = ss.str();

        bool allMatch = all_of(logs.begin(), logs.end(), [answer](const auto& log) { return check(log.first, answer, log.second);});
        if (allMatch) {
            candidates.push_back(answer);
        }
    }

    if (candidates.size() == 1) {
        cout << candidates[0] << endl;
    } else {
        cout << "NA" << endl;
    }

    return 0;
}

希望这个专栏能让您熟练掌握算法, 🎁🎁🎁 立即订阅

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

#面经##华为OD##华为OD题库##春招##秋招#
C++笔试真题题解 文章被收录于专栏

笔试真题题解

全部评论

相关推荐

评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务