rustgym/leetcode/
_529_minesweeper.rs1struct Solution;
2
3use std::collections::VecDeque;
4
5struct Point {
6 i: usize,
7 j: usize,
8}
9
10macro_rules! point {
11 ($i:expr,$j:expr) => {
12 Point { i: $i, j: $j }
13 };
14}
15
16impl Point {
17 fn adj(&self, n: usize, m: usize) -> Vec<Point> {
18 let mut res: Vec<Point> = vec![];
19 for i in -1..=1 {
20 for j in -1..=1 {
21 let r = self.i as i32 + i;
22 let c = self.j as i32 + j;
23 if r < 0 || r > (n - 1) as i32 || c < 0 || c > (m - 1) as i32 {
24 continue;
25 }
26 res.push(point!(r as usize, c as usize))
27 }
28 }
29 res
30 }
31}
32
33impl Solution {
34 fn update_board(mut board: Vec<Vec<char>>, click: Vec<i32>) -> Vec<Vec<char>> {
35 let n = board.len();
36 let m = board[0].len();
37 let i = click[0] as usize;
38 let j = click[1] as usize;
39 if board[i][j] == 'M' {
40 board[i][j] = 'X';
41 return board;
42 }
43 let mut visited: Vec<Vec<bool>> = vec![vec![false; m]; n];
44 let mut queue: VecDeque<Point> = VecDeque::new();
45 queue.push_back(Point { i, j });
46 while let Some(p) = queue.pop_front() {
47 visited[p.i][p.j] = true;
48 if board[p.i][p.j] == 'E' {
49 let mut sum = 0;
50 for q in p.adj(n, m) {
51 if board[q.i][q.j] == 'M' {
52 sum += 1;
53 }
54 }
55 if sum == 0 {
56 board[p.i][p.j] = 'B';
57 for q in p.adj(n, m) {
58 if !visited[q.i][q.j] {
59 queue.push_back(q);
60 }
61 }
62 } else {
63 board[p.i][p.j] = (b'0' + sum) as char;
64 }
65 }
66 }
67 board
68 }
69}
70
71#[test]
72fn test() {
73 let board = vec_vec_char![
74 ['E', 'E', 'E', 'E', 'E'],
75 ['E', 'E', 'M', 'E', 'E'],
76 ['E', 'E', 'E', 'E', 'E'],
77 ['E', 'E', 'E', 'E', 'E']
78 ];
79 let click = vec![3, 0];
80 let res = vec_vec_char![
81 ['B', '1', 'E', '1', 'B'],
82 ['B', '1', 'M', '1', 'B'],
83 ['B', '1', '1', '1', 'B'],
84 ['B', 'B', 'B', 'B', 'B']
85 ];
86 assert_eq!(Solution::update_board(board, click), res);
87}