牛客_[NOIP2002_普及组]_过河卒

[NOIP2002 普及组] 过河卒
https://www.nowcoder.com/practice/8439d41faa254418a3146c8cc0a68d62

import java.util.*;

/**
 * NC369 [NOIP2002 普及组] 过河卒
 * @author d3y1
 */
public class Solution {
    private boolean[][] isHorsePoint;
    private final int[] dx = new int[]{1, 1, -1, -1, 2, 2, -2, -2};
    private final int[] dy = new int[]{2, -2, 2, -2, 1, -1, 1, -1};

    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param n int整型 棋盘行数
     * @param m int整型 棋盘列数
     * @param x int整型 马的横坐标
     * @param y int整型 马的纵坐标
     * @return int整型
     */
    public int crossRiver (int n, int m, int x, int y) {
        return solution(n, m, x, y);
    }

    /**
     * 动态规划
     *
     * dp[i][j]表示卒从点A(0,0)能够到达点(i,j)的路径条数
     * 
     *            { 0                        , isHorsePoint[i][j]=true
     *            { 1                        , isHorsePoint[i][j]=false && i==0 && j==0
     * dp[i][j] = { dp[i][j-1]               , isHorsePoint[i][j]=false && i==0 && j>0
     *            { dp[i-1][j]               , isHorsePoint[i][j]=false && i>0 && j==0
     *            { dp[i][j-1] + dp[i-1][j]  , isHorsePoint[i][j]=false && i>0 && j>0
     *
     * @param n
     * @param m
     * @param x
     * @param y
     * @return
     */
    private int solution(int n, int m, int x, int y){
        isHorsePoint = new boolean[n+1][m+1];
        markHorsePoint(n, m, x, y);

        int[][] dp = new int[n+1][m+1];

        for(int i=0; i<=n; i++){
            for(int j=0; j<=m; j++){
                if(!isHorsePoint[i][j]){
                    if(i==0 && j==0){
                        dp[i][j] = 1;
                    }else if(i==0 && j>0){
                        dp[i][j] = dp[i][j-1];
                    }else if(i>0 && j==0){
                        dp[i][j] = dp[i-1][j];
                    }else{
                        dp[i][j] = dp[i][j-1] + dp[i-1][j];
                    }
                }
            }
        }

        return dp[n][m];
    }

    /**
     * 标记马点: 马所在点 + 马跃控点
     * @param n
     * @param m
     * @param x
     * @param y
     */
    private void markHorsePoint(int n, int m, int x, int y){
        // 马所在点
        if(isValid(n, m, x, y)){
            isHorsePoint[x][y] = true;
        }
        // 马跃控点
        for(int i=0; i<8; i++){
            if(isValid(n, m, x+dx[i], y+dy[i])){
                isHorsePoint[x+dx[i]][y+dy[i]] = true;
            }
        }
    }

    /**
     * 是否合法: 坐标(x,y)
     * @param n
     * @param m
     * @param x
     * @param y
     * @return
     */
    private boolean isValid(int n, int m, int x, int y){
        if(x<0 || n<x || y<0 || m<y){
            return false;
        }

        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值