你敢信,不会点算法没准你赛尔号都玩不明白

简单介绍一下背景,,这是赛尔号手游的一个游戏任务,叫做青龙祭坛,是获取青龙这个精灵的前置条件。下面是这个任务的截图

规则

要求是将所有的灯点亮,我对规则做了抽象,然后把这部分简单说明一下

有1,2,3,4,5,6,7个据点。 可以选择一个熄灭的据点点亮,点亮的规则如下。

  • 选择点亮的 据点后,可以点亮该据点和改据点对面的两个据点。 如果对面的两个据点有点亮状态的那么会将其熄灭,如果本身熄灭的会亮起
  • 据点的对应规则如下
    • 点亮 1 据点 对应 的点是 4 ,5 据点,
    • 点亮 2 据点对应的是 5, 6 据点。
    • 点亮 3 据点对应的是 6,7据点。 依次类推。 最后点亮7据点对应的是 的据点是3,4。

目前节点的状态是2,6 熄灭(数据格式 array<boolean>的数组) 请问 接下来这么做使得据点全部被点亮,要求 输出是 array<number>的数组, 含义是第 i + 1 步时应该进行操作的据点

input example:

arduino 复制代码
[true, false, true, true, true, false, true];

output example

csharp 复制代码
[2, 5, 1, 2, 4, 7, 3, 4]

如果有一点刷算法题的经验,那么答案其实已经呼之欲出了

那么大家是怎么做的呢

大多数人的做法是通过手动验证,又或者直接找一个前人验证后的路线走一遍

下面 截取b站这个任务的攻略,可以看出其实用的大多都是一种刀耕火种的求解方式

另一个up 攻略的评论区

解法示例

一个简单的bfs标记 visited,模版直接秒了

javascript 复制代码
// 定义每个据点对应的对面据点
const OPPOSITE_POINTS = {
    1: [4, 5],
    2: [5, 6], 
    3: [6, 7],
    4: [7, 1],
    5: [1, 2],
    6: [2, 3],
    7: [3, 4]
};

/**
 * 将据点状态转换为数字表示
 * @param {Array} state - 据点状态数组,true表示点亮,false表示熄灭
 * @returns {number} - 状态对应的数字
 */
function stateToNumber(state) {
    return parseInt(state.map(s => s ? '1' : '0').join(''), 2);
}

/**
 * 将数字转换为据点状态
 * @param {number} num - 状态数字
 * @returns {Array} - 据点状态数组
 */
function numberToState(num) {
    const binary = num.toString(2).padStart(7, '0');
    return binary.split('').map(bit => bit === '1');
}

/**
 * 执行一次点亮操作
 * @param {Array} currentState - 当前状态
 * @param {number} point - 要操作的据点编号(1-7)
 * @returns {Array} - 操作后的新状态
 */
function togglePoint(currentState, point) {
    const newState = [...currentState];
    const pointIndex = point - 1; // 转换为数组索引
    
    // 切换当前据点状态
    newState[pointIndex] = !newState[pointIndex];
    
    // 切换对面两个据点状态
    const oppositePoints = OPPOSITE_POINTS[point];
    for (const oppositePoint of oppositePoints) {
        const oppositeIndex = oppositePoint - 1;
        newState[oppositeIndex] = !newState[oppositeIndex];
    }
    
    return newState;
}

/**
 * 检查状态是否全部点亮
 * @param {Array} state - 据点状态
 * @returns {boolean} - 是否全部点亮
 */
function isAllLighted(state) {
    return state.every(point => point);
}

/**
 * 获取所有可能的下一步操作
 * @param {Array} state - 当前状态
 * @returns {Array} - 可操作的据点列表
 */
function getAvailableMoves(state) {
    const moves = [];
    for (let i = 0; i < state.length; i++) {
        if (!state[i]) { // 只选择熄灭的据点
            moves.push(i + 1);
        }
    }
    return moves;
}

/**
 * 使用BFS寻找最短解决方案
 * @param {Array} initialState - 初始状态
 * @returns {Array|null} - 解决方案路径,如果没有解则返回null
 */
function solveLightingPuzzle(initialState) {
    const queue = [{ state: initialState, path: [] }];
    const visited = new Set();
    
    while (queue.length > 0) {
        const { state, path } = queue.shift();
        const stateNum = stateToNumber(state);
        
        if (visited.has(stateNum)) {
            continue;
        }
        visited.add(stateNum);
        
        // 检查是否达到目标状态
        if (isAllLighted(state)) {
            return path;
        }
        
        // 获取所有可能的下一步操作
        const availableMoves = getAvailableMoves(state);
        
        for (const move of availableMoves) {
            const newState = togglePoint(state, move);
            const newPath = [...path, move];
            queue.push({ state: newState, path: newPath });
        }
    }
    
    return null; // 没有找到解决方案
}

/**
 * input: Array<boolean>
 * output: Array<number>
 */

/**
 * 主函数
 */
function main() {
    // 初始状态:2和6号据点熄灭,其他点亮
    const initialState = [true, false, true, true, true, false, true];
    
    const solution = solveLightingPuzzle(initialState);
    console.log(solution);
    return solution;
}

// 运行程序
main();

最后用cursor顺手补了一个界面

electroluxcode.github.io/front-knowl...

相关推荐
鸽鸽程序猿12 分钟前
【刷题册】二
算法
dlhto13 分钟前
前端登录验证码组件
前端
@万里挑一15 分钟前
vue中使用虚拟列表,封装虚拟列表
前端·javascript·vue.js
黑臂麒麟19 分钟前
Electron for OpenHarmony 跨平台实战开发:Electron 文件系统操作实战
前端·javascript·electron·openharmony
wordbaby19 分钟前
Tanstack Router 文件命名速查表
前端
CoderCodingNo22 分钟前
【GESP】C++四级真题 luogu-B4416 [GESP202509 四级] 最长连续段
开发语言·c++·算法
xjxijd22 分钟前
工业元宇宙 IDC 支撑:数字孪生算法 + 边缘服务器,生产调度响应速度提 3 倍
运维·服务器·算法
a程序小傲24 分钟前
京东Java面试被问:Fork/Join框架的使用场景
java·开发语言·后端·postgresql·面试·职场和发展
1024肥宅26 分钟前
工程化工具类:模块化系统全解析与实践
前端·javascript·面试
软件技术NINI27 分钟前
如何学习前端
前端·学习