2024华为OD试题及答案-A002-猜数字

题目描述

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

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

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

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

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

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

输入描述

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

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

输出描述

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

用例
输入6
4815 1A1B
5716 0A1B
7842 0A1B
4901 0A0B
8585 3A0B
8555 2A1B
输出3585
说明

问题解析

题目要求通过一组猜测数字和相应的提示,找出唯一确定的谜底数字。如果无法确定谜底数字,则输出NA

每个猜测数字和提示的格式如下:

  • XAYB:其中 X 表示数字位置和数值都正确的个数,Y 表示数值正确但位置错误的个数。

举个例子:

  • 当谜底为 8123,而猜测为 1052 时,提示应为 0A2B
  • 当谜底为 5637,而猜测为 4931 时,提示应为 1A0B

输入输出

输入:

  1. 一个正整数 N,表示猜测的次数(0 < N < 100)。
  2. 接下来 N 行,每行包含一个猜测的数字和提示结果。

输出:

  • 最后谜底的数字。如果无法确定,则输出 NA

C语言实现

我们可以通过枚举所有可能的谜底(即10000个四位数),然后根据给定的所有提示逐一验证每个谜底是否符合所有提示条件。如果有且只有一个符合条件的谜底,则输出该谜底;否则输出NA

代码实现

#include <stdio.h>
#include <string.h>

// 检查给定谜底与猜测之间的提示是否一致
int check_hint(const char *guess, const char *hint, const char *answer) {
    int a = 0, b = 0;
    int guess_digits[10] = {0};
    int answer_digits[10] = {0};

    // 计算A的数量
    for (int i = 0; i < 4; i++) {
        if (guess[i] == answer[i]) {
            a++;
        } else {
            guess_digits[guess[i] - '0']++;
            answer_digits[answer[i] - '0']++;
        }
    }

    // 计算B的数量
    for (int i = 0; i < 10; i++) {
        b += (guess_digits[i] < answer_digits[i]) ? guess_digits[i] : answer_digits[i];
    }

    // 检查提示是否一致
    return (hint[0] - '0' == a && hint[2] - '0' == b);
}

int main() {
    int N;
    scanf("%d", &N);

    char guesses[N][5];
    char hints[N][5];

    // 读取猜测和提示
    for (int i = 0; i < N; i++) {
        scanf("%s %s", guesses[i], hints[i]);
    }

    char answer[5];
    int possible_answers = 0;

    // 枚举所有可能的谜底
    for (int i = 0; i < 10000; i++) {
        sprintf(answer, "%04d", i);
        int valid = 1;
        for (int j = 0; j < N; j++) {
            if (!check_hint(guesses[j], hints[j], answer)) {
                valid = 0;
                break;
            }
        }
        if (valid) {
            possible_answers++;
            strcpy(answer, answer);
        }
    }

    // 输出结果
    if (possible_answers == 1) {
        printf("%s\n", answer);
    } else {
        printf("NA\n");
    }

    return 0;
}

代码说明:

  1. check_hint函数:检查给定谜底与猜测之间的提示是否一致。
  2. main函数
    • 读取输入的猜测和提示。
    • 枚举所有可能的谜底(0000到9999)。
    • 验证每个可能的谜底是否符合所有提示。
    • 如果有且只有一个符合条件的谜底,则输出该谜底,否则输出NA

Python 实现

def check_hint(guess, hint, answer):
    a = 0
    b = 0
    guess_digits = [0] * 10
    answer_digits = [0] * 10

    # 计算A的数量
    for i in range(4):
        if guess[i] == answer[i]:
            a += 1
        else:
            guess_digits[int(guess[i])] += 1
            answer_digits[int(answer[i])] += 1

    # 计算B的数量
    for i in range(10):
        b += min(guess_digits[i], answer_digits[i])

    # 检查提示是否一致
    return (int(hint[0]) == a and int(hint[2]) == b)

def main():
    # 读取输入
    N = int(input())
    
    guesses = []
    hints = []

    for _ in range(N):
        guess, hint = input().split()
        guesses.append(guess)
        hints.append(hint)

    possible_answers = 0
    final_answer = ''

    # 枚举所有可能的谜底
    for i in range(10000):
        answer = f"{i:04}"
        valid = True
        for j in range(N):
            if not check_hint(guesses[j], hints[j], answer):
                valid = False
                break
        if valid:
            possible_answers += 1
            final_answer = answer

    # 输出结果
    if possible_answers == 1:
        print(final_answer)
    else:
        print("NA")

if __name__ == "__main__":
    main()

代码说明:

  1. check_hint函数: 检查给定谜底与猜测之间的提示是否一致。
  2. main函数:
    • 读取输入的猜测和提示。
    • 枚举所有可能的谜底(0000到9999)。
    • 验证每个可能的谜底是否符合所有提示。
    • 如果有且只有一个符合条件的谜底,则输出该谜底,否则输出NA

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值