C解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

JS解法

找到一个唯一的4位数字组合,满足所有提示hints。
每条提示由一个猜测guess和结果result组成:
result的格式为xAyB,表示:
xA:有x个数字的位置和数值都正确。
yB:有y个数字的数值正确但位置不正确。
优化解法:

使用位操作和递归进行优化:
位操作用于记录每个位置可能的数字,减少枚举范围。
深度优先搜索(DFS)用于生成可能的密码组合并验证其有效性。
主要步骤:

初始化可能性数组:
每个位置的可能数字初始为(1 << 10) - 1(即0-9全部可能)。
根据提示逐步更新可能性数组,排除不符合的数字。
深度优先搜索生成候选密码:
按位置递归生成所有可能的4位数字组合。
对每个组合,验证是否满足所有提示。
验证密码有效性:
对每条提示,计算猜测和密码的xAyB值,并与提示结果对比。
关键逻辑:

位操作:
使用poss数组记录每个位置可能的数字集合。
通过按位与和按位取反,动态更新可能的数字集合。
DFS递归:
遍历可能的数字集合,逐个尝试生成密码,并进行验证。

const rl = require('readline').createInterface({ input: process.stdin, output: process.stdout });
const io = [];
rl.on('line', ln => io.push(ln)).on('close', main);

function main() {
    const [n, ...data] = io; // 读取输入的提示数量和提示内容
    console.log(solve(data.map(x => x.split(' ')))); // 解析提示并求解
}

function solve(hints) {
    // 初始化每个位置可能的数字集合,初始为0-9全部可能
    let poss = Array(4).fill((1 << 10) - 1);

    // 根据提示更新可能性数组
    for (let [g, r] of hints) {
        let [a, b] = r.split('A'); // 提取结果的xA和yB
        b = b[0]; // 只需要y的值

        if (a == '0') { // 如果提示xA为0
            for (let i = 0; i < 4; i++) {
                if (b == '0') {
                    // 如果yB为0,数字在该位置不可能出现
                    poss[i] &= ~(1 << +g[i]);
                } else {
                    // 否则,该数字可能出现在其他位置,但不能同时占多个位置
                    poss[i] &= ~(1 << +g[i]) | (1 << 10);
                }
            }
        }
    }

    // 用于存储符合条件的候选密码
    let res = [];
    // 开始DFS搜索符合条件的密码
    dfs(0, [], poss, hints, res);

    // 如果只有一个符合条件的密码,返回该密码;否则返回"NA"
    return res.length === 1 ? res[0].join('') : 'NA';
}

// 深度优先搜索,生成密码组合并验证其有效性
function dfs(idx, curr, poss, hints, res) {
    if (idx === 4) { // 如果已生成4位密码
        if (isValid(curr, hints)) res.push([...curr]); // 验证密码是否有效
        return;
    }
    for (let i = 0; i < 10; i++) {
        if (poss[idx] & (1 << i)) { // 检查当前位置是否可能为数字i
            curr.push(i); // 将数字i加入当前密码组合
            dfs(idx + 1, curr, poss, hints, res); // 递归处理下一位
            curr.pop(); // 回溯,移除当前数字
        }
    }
}

// 验证当前密码是否满足所有提示
function isValid(guess, hints) {
    for (let [g, r] of hints) {
        let [a, b] = calcAB(guess, g.split('').map(Number)); // 计算实际的xA和yB
        if (a != r[0] || b != r[2]) return false; // 如果不匹配,返回false
    }
    return true; // 所有提示均匹配,返回true
}

// 计算猜测和答案的xA和yB值
function calcAB(ans, guess) {
    let a = 0, b = 0;
    let m1 = Array(10).fill(0), m2 = Array(10).fill(0);

    // 遍历4位数字
    for (let i = 0; i < 4; i++) {
        if (ans[i] === guess[i]) {
            a++; // 数字和位置都正确,增加xA
        } else {
            m1[ans[i]]++; // 记录答案中的数字
            m2[guess[i]]++; // 记录猜测中的数字
        }
    }

    // 计算yB:取每个数字出现次数的最小值
    for (let i = 0; i < 10; i++) b += Math.min(m1[i], m2[i]);

    return [a, b]; // 返回xA和yB
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/145052761"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!