2025华为od机试真题B卷【连连看游戏】JavaScript实现

目录

题目

思路

Code


题目

小明在玩连连看游戏,目标是消除相同的数字,游戏规定:

  • 两个位置必须数字相同才能消除
  • 连接路径只能经过空格
  • 连接路径最多只能有两次拐弯
  • 连接线路可以走地图的边界
  • 消除后位置变为空格("")

第一行输入一个数组代表连连看的地图矩阵,形式类似于: [[4,5,4] [5,4,5]] ,第一行输入n,表示操作步骤数,接下来r行,每行输入四个数字 y1 x1 y2 x2 代表此次操作的两个位置。题目要求判断按照操作步骤执行,是否每一步都能进行消除,可以的话输出 OK,否则输出 NO。
输入描述
第一行输入 一个字符串,代表 连连看的地图。
第二行输出一个 n,代表操作步骤数
接下来的n行,每一行输入y1 x1 y2 x2 代表此次操作的两个表格位置
备注
不必考虑输入不合法的情况
输出描述
输入步骤能全部正常消除则输出 OK 。否则输出 NO

示例1:

输入:

[[4,5,4],[5,4,5]]
2
0 0 2 0
1 0 0 1

输出:

OK

说明:

位置(0,0)到位置(0,2)上,都是4,可以消除

位置(0,1)到位置(1,0)上,都是5,可以消除

思路

解题思路

地图预处理

  • 解析输入字符串为二维数组
  • 添加边界,使用空格填充
  • 便于处理边界情况

路径搜索策略

  • 使用DFS深度优先搜索
  • 记录已访问位置避免循环
  • 记录每个位置的最小拐弯数进行剪枝
  • 四个方向搜索:上、下、左、右

关键优化点

  • 使用位置索引优化访问记录
  • 方向编码优化拐弯判断
  • 提前剪枝减少搜索空间

Code

// 方向数组:上下左右
const DIRECTION_X = [-1, 1, 0, 0];
const DIRECTION_Y = [0, 0, -1, 1];

// 解析地图字符串
function processGameMap(inputStr) {
    // 移除外层括号
    inputStr = inputStr.slice(2, -2);
    const rows = inputStr.split('],[');
    
    // 创建初始地图
    const gameMap = rows.map(row => row.split(','));
    
    // 获取尺寸
    const rowCnt = gameMap.length;
    const colCnt = gameMap[0].length;
    
    // 创建带边界的新地图
    const borderedMap = Array(rowCnt + 2).fill().map(() => 
        Array(colCnt + 2).fill(' '));
    
    // 填充数据
    for (let i = 0; i < rowCnt; i++) {
        for (let j = 0; j < colCnt; j++) {
            borderedMap[i + 1][j + 1] = gameMap[i][j];
        }
    }
    
    return borderedMap;
}

// DFS搜索路径
function explorePath(board, currX, currY, targetX, targetY, currDir, turns, visited, minTurns) {
    const rowCnt = board.length;
    const colCnt = board[0].length;
    const posIdx = currX * colCnt + currY;
    
    // 剪枝条件
    if (currDir !== -1 && turns >= minTurns[posIdx][currDir]) return false;
    if (turns > 2) return false;
    
    // 更新最小拐弯数
    if (currDir !== -1) minTurns[posIdx][currDir] = turns;
    
    // 到达目标
    if (currX === targetX && currY === targetY) return true;
    
    // 探索四个方向
    for (let nextDir = 0; nextDir < 4; nextDir++) {
        const nextX = currX + DIRECTION_X[nextDir];
        const nextY = currY + DIRECTION_Y[nextDir];
        
        // 边界检查
        if (nextX < 0 || nextX >= rowCnt || nextY < 0 || nextY >= colCnt) continue;
        
        // 访问检查
        const key = `${nextX},${nextY}`;
        if (visited.has(key)) continue;
        
        // 路径检查
        if (!(nextX === targetX && nextY === targetY) && board[nextX][nextY] !== ' ') continue;
        
        // 计算拐弯
        const nextTurns = turns + (currDir !== -1 && currDir !== nextDir ? 1 : 0);
        
        // 记录访问
        visited.add(key);
        
        if (explorePath(board, nextX, nextY, targetX, targetY,
                       nextDir, nextTurns, visited, minTurns)) {
            return true;
        }
        
        visited.delete(key);
    }
    
    return false;
}

// 检查连接
function verifyConnection(board, x1, y1, x2, y2) {
    if (board[x1][y1] !== board[x2][y2]) return false;
    if (x1 === x2 && y1 === y2) return false;
    
    const rowCnt = board.length;
    const colCnt = board[0].length;
    
    // 初始化最小拐弯数数组
    const minTurns = Array(rowCnt * colCnt).fill().map(() => 
        Array(4).fill(Infinity));
    
    // 初始化访问集合
    const visited = new Set([`${x1},${y1}`]);
    
    if (explorePath(board, x1, y1, x2, y2, -1, 0, visited, minTurns)) {
        board[x1][y1] = ' ';
        board[x2][y2] = ' ';
        return true;
    }
    return false;
}

// 主函数
function main(input) {
    const lines = input.trim().split('\n');
    const gameBoard = processGameMap(lines[0]);
    const operationCount = parseInt(lines[1]);
    
    for (let i = 0; i < operationCount; i++) {
        const [y1, x1, y2, x2] = lines[i + 2].split(' ').map(x => parseInt(x) + 1);
        
        if (!verifyConnection(gameBoard, x1, y1, x2, y2)) {
            console.log("NO");
            return;
        }
    }
    
    console.log("OK");
}

// 处理输入(Node.js环境)
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let inputString = '';
process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});
process.stdin.on('end', () => {
    main(inputString);
});

【华为od机试真题Python+JS+Java合集】【超值优惠】:Py/JS/Java合集

【华为od机试真题Python】:Python真题题库

【华为od机试真题JavaScript】:JavaScript真题题库

【华为od机试真题Java】:Java真题题库

【华为od机试真题C++】:C++真题题库

【华为od机试真题C语言】:C语言真题题库

【华为od面试手撕代码题库】:面试手撕代码题库

【华为od机试面试交流群:830285880】

华为OD机试:二本院校有机会吗?
有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。

### 关于华为OD2025 A的信息 目前尚未有公开发布的具体关于2025华为ODA的官方题目或考大纲。然而,基于以往的趋势以及已有的资料[^1],可以推测该考将继续沿袭之前的技术考察方向和形式。 #### 技术考察范围预测 根据过往几年的考内容分析,尤其是从2023年的JS、C++、Java、Python等编程语言涉及的内容来看[^2],预计2025年的A仍将以算法设计、数据结构应用为核心考点,并可能增加对新兴技术栈的支持程度评估,比如Go语言的应用场景扩展[^3]。 以下是几个主要方面: - **基础算法与复杂度分析**:包括但不限于快速排序实现[^4]、动态规划求解最优化问题等经典算法及其时间空间效率考量。 - **高级数据结构运用**:链表操作、树形遍历(如二叉搜索树)、图论基本概念及其实现方法。 - **实际工程能力测**:通过模拟真实工作环境中的编码挑战来检验考生解决实际业务逻辑的能力,这通常体现在一些特定应用场景下的字符串处理或者数组变换等问题上。 #### 示例代码片段展示 下面给出一段简单的快速排序函数作为例子: ```python def quick_sort(arr): if len(arr) <= 1: return arr else: pivot = arr[len(arr)//2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left)+middle+quick_sort(right) ``` 此段代码展示了如何利用分治法思想构建递归式的解决方案,在面对大规模无序列表时能够有效提升性能表现[^5]。 #### 复习建议 为了更好地准备即将到来的2025年度华为ODA,推荐采取如下策略: - 定期刷LeetCode或其他在线判题平台上的高频面题; - 加强对于计算科学基础知识的理解掌握,特别是那些容易被忽视却极其重要的细节之处; - 参加各类竞赛活动积累实战经验的同时也锻炼心理素质;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MISAYAONE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值