news 2026/8/21 14:02:58

华为OD机试黑白棋算法解析与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
华为OD机试黑白棋算法解析与实现

1. 项目概述:华为OD机试中的黑白棋棋盘问题

黑白棋(又称翻转棋)是一种经典的策略性棋盘游戏,在华为OD机试中常作为考察编程能力的题目出现。这类题目通常给定一个N×N的棋盘,要求选手编写程序计算棋子的合法移动范围或最优落子位置。题目不仅考察基础编程能力,更检验选手对二维数组操作、递归搜索和游戏规则的掌握程度。

在实际机试环境中,这类题目往往要求使用Python或JavaScript两种语言实现。Python因其简洁的语法和丰富的数据结构成为首选,而JavaScript则因前端开发岗位的需求被纳入考察范围。题目通常会提供棋盘初始状态和当前玩家颜色(黑/白),要求输出所有合法移动位置或最优策略。

提示:华为OD机试对时间复杂度和空间复杂度有严格要求,暴力解法通常无法通过全部测试用例,需要优化算法效率。

2. 核心算法解析与实现思路

2.1 黑白棋基本规则建模

黑白棋的核心规则是"夹吃"——当一方在棋盘上放置一枚棋子后,如果在横、竖、斜任一方向上,新棋子与己方另一枚棋子之间全部是对手的棋子,则这些对手棋子全部翻转为我方颜色。实现这一规则需要八个方向的遍历检查:

# 定义8个移动方向向量 DIRECTIONS = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)]

对于每个空白格子,我们需要检查:

  1. 相邻格子是否为对手颜色
  2. 沿该方向继续查找是否以己方颜色结尾
  3. 若满足条件,则记录该位置为合法落子点

2.2 合法移动位置判定算法

实现合法移动判定的关键步骤如下:

  1. 遍历棋盘每个空白位置
  2. 对每个空白位置,检查8个方向
  3. 对每个方向进行深度搜索:
    • 相邻格子必须是对手颜色
    • 后续连续格子必须全是对手颜色
    • 最终必须以己方颜色结尾
  4. 若任一方向满足条件,则该位置为合法落子点

JavaScript实现示例:

function isValidMove(board, row, col, player) { if (board[row][col] !== 0) return false; const opponent = 3 - player; // 对手颜色 let valid = false; for (const [dx, dy] of DIRECTIONS) { let x = row + dx, y = col + dy; let hasOpponent = false; while (x >= 0 && x < N && y >= 0 && y < N) { if (board[x][y] === opponent) { hasOpponent = true; x += dx; y += dy; } else if (board[x][y] === player && hasOpponent) { valid = true; break; } else { break; } } } return valid; }

2.3 棋盘状态更新逻辑

当确定合法落子位置后,需要实现棋子翻转逻辑。这需要:

  1. 复制当前棋盘状态(避免修改原数组)
  2. 在新位置放置当前玩家棋子
  3. 对每个有效方向:
    • 沿方向遍历直到遇到己方棋子
    • 将途中所有对手棋子翻转为己方颜色

Python实现示例:

def make_move(board, row, col, player): new_board = [row[:] for row in board] new_board[row][col] = player opponent = 3 - player for dx, dy in DIRECTIONS: x, y = row + dx, col + dy to_flip = [] while 0 <= x < N and 0 <= y < N: if new_board[x][y] == opponent: to_flip.append((x, y)) x += dx y += dy elif new_board[x][y] == player and to_flip: for (fx, fy) in to_flip: new_board[fx][fy] = player break else: break return new_board

3. 性能优化与华为OD机试技巧

3.1 算法复杂度分析

基础实现的时间复杂度为O(N^3):

  • 遍历棋盘:O(N^2)
  • 每个位置检查8个方向:O(N) 在N=8的标准棋盘下尚可接受,但当N增大时(如华为OD测试用例中N可能达到100),需要优化。

3.2 关键优化策略

  1. 预计算合法移动位置:维护一个合法位置缓存,只在棋子落子后更新受影响区域
  2. 位棋盘表示法:使用位运算加速状态判断(特别适合JS实现)
  3. Alpha-Beta剪枝:当题目要求最优策略时,使用博弈树搜索优化

JavaScript位运算优化示例:

// 使用Uint32Array表示棋盘行 let blackBoard = new Uint32Array(N); let whiteBoard = new Uint32Array(N); // 快速检查方向是否有效 function checkDirection(mask, opponentMask, start, step) { let current = start + step; let hasOpponent = false; while (current >= 0 && current < N) { if (opponentMask & (1 << current)) { hasOpponent = true; current += step; } else if (mask & (1 << current) && hasOpponent) { return true; } else { break; } } return false; }

3.3 华为OD机试特殊要求

  1. 输入输出格式:严格按照题目要求的格式处理输入输出
  2. 边界条件:特别注意N=1和N=100的极端情况
  3. 时间限制:Python/JS在华为OD环境中运行速度较慢,需提前测试

注意:华为OD机试禁止使用某些内置库(如Python的numpy),需使用标准库实现

4. 完整代码实现与测试用例

4.1 Python完整实现

def solve_othello(N, board, player): DIRECTIONS = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)] def is_valid(r, c): if board[r][c] != 0: return False opponent = 3 - player for dr, dc in DIRECTIONS: nr, nc = r + dr, c + dc found_opponent = False while 0 <= nr < N and 0 <= nc < N: if board[nr][nc] == opponent: found_opponent = True nr += dr nc += dc elif board[nr][nc] == player and found_opponent: return True else: break return False result = [] for i in range(N): for j in range(N): if is_valid(i, j): result.append(f"{i},{j}") return result if result else ["NULL"] # 示例输入处理 N = int(input()) board = [] for _ in range(N): row = list(map(int, input().split())) board.append(row) player = int(input()) # 输出结果 print("\n".join(solve_othello(N, board, player)))

4.2 JavaScript完整实现

function solveOthello(N, board, player) { const DIRECTIONS = [[-1,-1], [-1,0], [-1,1], [0,-1], [0,1], [1,-1], [1,0], [1,1]]; function isValid(r, c) { if (board[r][c] !== 0) return false; const opponent = 3 - player; for (const [dr, dc] of DIRECTIONS) { let nr = r + dr, nc = c + dc; let foundOpponent = false; while (nr >= 0 && nr < N && nc >= 0 && nc < N) { if (board[nr][nc] === opponent) { foundOpponent = true; nr += dr; nc += dc; } else if (board[nr][nc] === player && foundOpponent) { return true; } else { break; } } } return false; } const result = []; for (let i = 0; i < N; i++) { for (let j = 0; j < N; j++) { if (isValid(i, j)) { result.push(`${i},${j}`); } } } return result.length > 0 ? result.join("\n") : "NULL"; } // 示例输入处理(华为OD环境可能不同) const input = require('fs').readFileSync(0).toString().trim().split('\n'); const N = parseInt(input[0]); const board = []; for (let i = 1; i <= N; i++) { board.push(input[i].split(' ').map(Number)); } const player = parseInt(input[N + 1]); // 输出结果 console.log(solveOthello(N, board, player));

4.3 测试用例设计

标准测试用例:

8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

预期输出(合法落子位置):

2,3 3,2 4,5 5,4

边界测试用例:

1 0 1

预期输出:

0,0

5. 常见问题与调试技巧

5.1 华为OD环境下的特殊问题

  1. 输入输出处理

    • Python使用input()读取,JS使用readline
    • 注意行尾可能有隐藏空白字符,需要trim()
  2. 递归深度限制

    • Python默认递归深度约1000,大N时需改迭代
    • JS调用栈限制也需考虑
  3. 性能瓶颈

    • 在N=100时,O(N^3)算法可能超时
    • 提前进行时间复杂度估算

5.2 调试技巧

  1. 打印中间状态

    def debug_board(board): for row in board: print(' '.join(map(str, row))) print()
  2. 单元测试验证

    • 单独测试is_valid函数
    • 验证小棋盘的手动计算结果
  3. 边界条件测试

    • 全空棋盘
    • 全满棋盘
    • 单行/单列棋盘

5.3 代码风格建议

  1. 华为OD评分标准

    • 变量命名清晰(避免单字符)
    • 适当添加注释
    • 函数模块化设计
  2. 防御性编程

    • 检查数组越界
    • 处理异常输入
    • 验证玩家颜色值
  3. 时间管理

    • 先实现基础功能
    • 通过测试用例后再优化
    • 预留10分钟检查边界条件
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/21 13:59:56

头歌实践教学平台:大数据存储2023(三~四)

三、Hive综合应用案例 — 用户搜索日志分析第1关&#xff1a;2018年点击量最高的10个网站域名任务描述 本关任务&#xff1a;分析2018年点击量最高的10个网站域名。编程要求 在右侧编辑器补充代码&#xff0c;分析出2018年点击量最高的10个网站域名。创建数据库&#xff1a;myd…

作者头像 李华
网站建设 2026/8/21 13:59:31

从单元测试学Unity开发:guid-based-reference测试套件深度解读

从单元测试学Unity开发&#xff1a;guid-based-reference测试套件深度解读 【免费下载链接】guid-based-reference A component for giving Game Objects a GUID and a class to create references to objects in any Scene by GUID 项目地址: https://gitcode.com/gh_mirror…

作者头像 李华
网站建设 2026/8/21 13:47:08

聊聊Oblique生态:Maven/JitPack集成、版本演进与作者开源故事

聊聊Oblique生态&#xff1a;Maven/JitPack集成、版本演进与作者开源故事 【免费下载链接】Oblique With Oblique explore new styles of displaying images 项目地址: https://gitcode.com/gh_mirrors/ob/Oblique Oblique 是一个开源免费的 Android 斜切图片展示库&…

作者头像 李华
网站建设 2026/8/21 13:46:11

AI大模型qwythos本地部署实战:从零搭建私有化智能引擎

最近&#xff0c;AI大模型领域的一个新名字“qwythos”开始频繁出现在技术社区的讨论中。很多开发者第一眼看到它&#xff0c;可能会被“超强无审查”这样的描述所吸引&#xff0c;但随之而来的是一连串问号&#xff1a;这又是一个昙花一现的“开源明星”&#xff0c;还是真正能…

作者头像 李华
网站建设 2026/8/21 13:45:23

多智能体强化学习对抗卫星通信CSI延迟:DS-PPO与注意力机制实战

1. 项目概述&#xff1a;当多卫星系统遇上“延迟”的挑战在构建一个由多颗卫星组成的协同网络时&#xff0c;我们总会遇到一个看似简单却极其棘手的问题&#xff1a;信息传递需要时间。想象一下&#xff0c;你在地面上指挥一支由多架无人机组成的编队&#xff0c;每架无人机都通…

作者头像 李华