leetcode 1958 题解
数组中的移动。

容易考虑不周全。

题目

给你一个下标从 0 开始的 8 x 8 网格 board ,其中 board[r][c] 表示游戏棋盘上的格子 (r, c) 。棋盘上空格用 '.' 表示,白色格子用 'W' 表示,黑色格子用 'B' 表示。

游戏中每次操作步骤为:选择一个空格子,将它变成你正在执行的颜色(要么白色,要么黑色)。但是,合法 操作必须满足:涂色后这个格子是 {mark % 好线段的一个端点} (好线段可以是水平的,竖直的或者是对角线)。

好线段 指的是一个包含 三个或者更多格子(包含端点格子)的线段,线段两个端点格子为 同一种颜色 ,且中间剩余格子的颜色都为 另一种颜色 (线段上不能有任何空格子)。你可以在下图找到好线段的例子:

给你两个整数 rMovecMove 以及一个字符 color ,表示你正在执行操作的颜色(白或者黑),如果将格子 (rMove, cMove) 变成颜色 color 后,是一个 合法 操作,那么返回 true ,如果不是合法操作返回 false

示例 1:

输入:board = [[“.”,”.”,”.”,”B”,”.”,”.”,”.”,”.”],[“.”,”.”,”.”,”W”,”.”,”.”,”.”,”.”],[“.”,”.”,”.”,”W”,”.”,”.”,”.”,”.”],[“.”,”.”,”.”,”W”,”.”,”.”,”.”,”.”],[“W”,”B”,”B”,”.”,”W”,”W”,”W”,”B”],[“.”,”.”,”.”,”B”,”.”,”.”,”.”,”.”],[“.”,”.”,”.”,”B”,”.”,”.”,”.”,”.”],[“.”,”.”,”.”,”W”,”.”,”.”,”.”,”.”]], rMove = 4, cMove = 3, color = “B”
输出:true
解释:’.’,’W’ 和 ‘B’ 分别用颜色蓝色,白色和黑色表示。格子 (rMove, cMove) 用 ‘X’ 标记。
以选中格子为端点的两个好线段在上图中用红色矩形标注出来了。

示例 2:

输入:board = [[“.”,”.”,”.”,”.”,”.”,”.”,”.”,”.”],[“.”,”B”,”.”,”.”,”W”,”.”,”.”,”.”],[“.”,”.”,”W”,”.”,”.”,”.”,”.”,”.”],[“.”,”.”,”.”,”W”,”B”,”.”,”.”,”.”],[“.”,”.”,”.”,”.”,”.”,”.”,”.”,”.”],[“.”,”.”,”.”,”.”,”B”,”W”,”.”,”.”],[“.”,”.”,”.”,”.”,”.”,”.”,”W”,”.”],[“.”,”.”,”.”,”.”,”.”,”.”,”.”,”B”]], rMove = 4, cMove = 4, color = “W”
输出:false
解释:虽然选中格子涂色后,棋盘上产生了好线段,但选中格子是作为中间格子,没有产生以选中格子为端点的好线段。

提示:

  • board.length == board[r].length == 8
  • 0 <= rMove, cMove < 8
  • board[rMove][cMove] == '.'
  • color 要么是 'B' 要么是 'W' 。

思路

一个数组用于移动下标,检查是否已经出界,如果没有出界,记录当前方向的字符,直至遇到 '.' 。可能产生的情况如下(假设当前方向为同一行、从左到右,要修改的格子记为 'M' ,修改后为 'B' ):

  1. M与当前方向的下一个格子相同,如 [M,B] ,返回 false
  2. 当前方向的前一个格子和后一个格子不同,如 [M,W,B] (假设已经考虑了第一种情况),返回 true
  3. 当前方向的前一个格子和后一个格子都相同,判断M与当前方向的最后一个格子,如 [M,W,W,W,B] ,返回 true

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Solution {
public:
bool check(int i, int j, int mi, int mj) {
if (i + mi >= 8 || i + mi < 0 || j + mj >= 8 || j + mj < 0)
return false;
return true;
}
bool oneDMove(vector<vector<char>>& board, int rMove, int cMove, char color, int mi, int mj) {
int count = 0;
char last = '.', origin = color;
char pan[8] = {'.'};
while (check(rMove, cMove, mi, mj)) {
rMove += mi;
cMove += mj;
if (board[rMove][cMove] == '.')
break;
pan[count] = board[rMove][cMove];
count++;
last = board[rMove][cMove];
}
if (count == 2) {
if (origin == last && origin != pan[0])
return true;
}
if (count > 2) {
if (origin != pan[0]) {
for (int i = 1; i < count - 1; i++) {
if (pan[i - 1] != pan[i])
return true;
}
if (origin == last)
return true;
}
}
return false;
}
bool checkMove(vector<vector<char>>& board, int rMove, int cMove,
char color) {
int move[8][2] = {{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}};
for (int i = 0; i < 8; i++) {
if (oneDMove(board, rMove, cMove, color, move[i][0], move[i][1]))
return true;
}
return false;
}
};