• [LeetCode] 999. Available Captures for Rook 国际象棋中车的可捕获量



    On an 8 x 8 chessboard, there is one white rook.  There also may be empty squares, white bishops, and black pawns.  These are given as characters 'R', '.', 'B', and 'p' respectively. Uppercase characters represent white pieces, and lowercase characters represent black pieces.

    The rook moves as in the rules of Chess: it chooses one of four cardinal directions (north, east, west, and south), then moves in that direction until it chooses to stop, reaches the edge of the board, or captures an opposite colored pawn by moving to the same square it occupies.  Also, rooks cannot move into the same square as other friendly bishops.

    Return the number of pawns the rook can capture in one move.

    Example 1:

    Input: [[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".","R",".",".",".","p"],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."]]
    Output: 3
    Explanation:
    In this example the rook is able to capture all the pawns.
    

    Example 2:

    Input: [[".",".",".",".",".",".",".","."],[".","p","p","p","p","p",".","."],[".","p","p","B","p","p",".","."],[".","p","B","R","B","p",".","."],[".","p","p","B","p","p",".","."],[".","p","p","p","p","p",".","."],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."]]
    Output: 0
    Explanation:
    Bishops are blocking the rook to capture any pawn.
    

    Example 3:

    Input: [[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".","p",".",".",".","."],["p","p",".","R",".","p","B","."],[".",".",".",".",".",".",".","."],[".",".",".","B",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".",".",".",".",".","."]]
    Output: 3
    Explanation:
    The rook can capture the pawns at positions b5, d6 and f5.
    

    Note:

    1. board.length == board[i].length == 8
    2. board[i][j] is either 'R''.''B', or 'p'
    3. There is exactly one cell with board[i][j] == 'R'

    这道题给了一个 8x8 大小的国际象棋棋盘,上面只能有三种棋子,分别是白方的车,白方的象,和黑方的兵,问白色方的车最多能吃到多个黑方的兵。在国际象棋中,车是可以上下左右走的,若某条路径上先遇到了白方的象,则该路上没法吃兵了,若先遇上了兵,可以吃,但此时后面若还有兵,不能连续吃。搞懂了题意其实很简单了,首先遍历棋盘,找到白方车的位置,然后最简单粗暴的方法是,四个方向分别用 for 循环来遍历,若遇到白方的象,直接 break,若遇到兵,则结果 res 自增1,然后 break 即可,参见代码如下:


    解法一:

    class Solution {
    public:
        int numRookCaptures(vector<vector<char>>& board) {
    		int x = 0, y = 0, res = 0;
    		for (int i = 0; i < 8; ++i) {
    			for (int j = 0; j < 8; ++j) {
    				if (board[i][j] == 'R') {
    					x = i; y = j; break;
    				}
    			}
    		}
    		for (int j = y; j >= 0; --j) {
    			if (board[x][j] == 'B') break;
    			if (board[x][j] == 'p') {++res; break;} 
    		}
    		for (int j = y; j < 8; ++j) {
    			if (board[x][j] == 'B') break;
    			if (board[x][j] == 'p') {++res; break;}  
    		}
    		for (int i = x; i >= 0; --i) {
    			if (board[i][y] == 'B') break;
    			if (board[i][y] == 'p') {++res; break;} 
    		}
    		for (int i = x; i < 8; ++i) {
    			if (board[i][y] == 'B') break;
    			if (board[i][y] == 'p') {++res; break;} 
    		}
    		return res;
        }
    };
    

    我们也可以不用写那么 for 循环,而是利用深度优先遍历 DFS 的思想,用方向数组,每次加上方向的偏移,若没有越界,则判断,若是黑兵,则结果 res 加1,若不是点,则 break,这判断很精髓,覆盖了当前是白象或黑兵的情况,保证了遇到了白象,或者已经吃了黑兵之后可以 break,然后继续增加偏移量直至退出循环,参见代码如下:


    解法二:

    class Solution {
    public:
        int numRookCaptures(vector<vector<char>>& board) {
            int x0 = 0, y0 = 0, res = 0;
            vector<vector<int>> dirs{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    		for (int i = 0; i < 8; ++i) {
    			for (int j = 0; j < 8; ++j) {
    				if (board[i][j] == 'R') {
    					x0 = i; y0 = j; break;
    				}
    			}
    		}
            for (auto &dir : dirs) {
                int x = x0 + dir[0], y = y0 + dir[1];
                while (x >= 0 && x < 8 && y >= 0 && y < 8) {
                    if (board[x][y] == 'p') ++res;
                    if (board[x][y] != '.') break;
                    x += dir[0]; y += dir[1];
                }
            }
            return res;
        }
    };
    

    Github 同步地址:

    https://github.com/grandyang/leetcode/issues/999


    参考资料:

    https://leetcode.com/problems/available-captures-for-rook/

    https://leetcode.com/problems/available-captures-for-rook/discuss/242924/C%2B%2BJava-search-and-capture

    https://leetcode.com/problems/available-captures-for-rook/discuss/242932/JavaC%2B%2BPython-Straight-Forward-Solution


    LeetCode All in One 题目讲解汇总(持续更新中...)

  • 相关阅读:
    Docker+Jenkins持续集成环境(1)使用Docker搭建Jenkins+Docker持续集成环境
    DockOne技术分享(二十):Docker三剑客之Swarm介绍
    最佳实战Docker持续集成图文详解
    Spring Cloud Netflix Eureka源码导读与原理分析
    JVM内存区域的划分(内存结构或者内存模型)
    深入理解JVM(一)——JVM内存模型
    java多线程有哪些实际的应用场景?
    深入理解Java类加载器(1):Java类加载原理解析
    【深入Java虚拟机】之四:类加载机制
    OAuth 2和JWT
  • 原文地址:https://www.cnblogs.com/grandyang/p/14277223.html
Copyright © 2020-2023  润新知