P1002过河卒

#题目#

棋盘上 A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示,A AA 点 (0,0)、B点 (n,m),同样马的位置坐标是需要给出的。

现在要求你计算出卒从 A 点能够到达 B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入格式
一行四个正整数,分别表示 B点坐标和马的坐标。

输出格式
一个整数,表示所有的路径条数。

输入输出样例
输入 #1

6 6 3 3

输出 #1

6

说明/提示
对于 100%100% 的数据,1≤n,m≤20,0≤ 马的坐标 ≤20。

解析
分析棋盘上到每个点的路径数目,如下图所示:

第一行和第一列是增加的边界,所以路径为0

据此,我们可以得出一个迭代式的(x,y)=(x-1,y)+(x,y-1).

动态规划检查是否越界时我们可以将整个图向右下方移动一个单位,空出一行一列便于越界检查。

象棋中马的走法是固定的(即马走日字),我们可以遍历马的八种走法(主要越界检查)。将马可以走的位置设为零。

初始化迭代时设(1,0)处=1,通过使用迭代式算出每一个点从A点可以到达的路径数,(也可以设(0,1)处=1,道理是相同的).

迭代完成后b点坐标处得出的路径数即为A到B得路径数。
 

java代码:

import java.util.Scanner;

public class luogu1002 {
    public static void main(String[] args) {
        int row,col,x,y;
        Scanner s=new Scanner(System.in);
        row=s.nextInt();
        col=s.nextInt();
        x=s.nextInt();
        y=s.nextInt();
        
    
        
        row++;
        col++;
        x++;
        y++;
        //初始化网格状态
        long[][] map=new long[row+1][col+1];
        
        for(int i=1;i<=row;i++)
            for(int j=1;j<=col;j++)
                map[i][j]=-1;
        
//        for(int i=0;i<=row;i++) {
//            map[i][0]=0;
//        }
//        for(int j=0;j<=col;j++) {
//            map[0][j]=0;
//        }

        map[1][1]=1;
        //马及马踏点置0
        map[x][y]=0;
        for(int i=-1;i<=1;i+=2) {
            if(x+1*i>0&&x+1*i<=row)
                for(int j=-1;j<=1;j+=2) {
                    if(y+2*j>0&&y+2*j<=col)
                        map[x+1*i][y+2*j]=0;
                }
        }
        for(int i=-1;i<=1;i+=2) {
            if(x+2*i>0&&x+2*i<=row)
                for(int j=-1;j<=1;j+=2) {
                    if(y+1*j>0&&y+1*j<=col)
                        map[x+2*i][y+1*j]=0;
                }
        }
        
//        //显示网格状态
//                for(int i=0;i<=row;i++) {
//                    for(int j=0;j<=col;j++) {
//                        System.out.printf("%3d ", map[i][j]);
//                    }
//                    System.out.println();
//                }
//        
//                System.out.println("------------------------------");
        
        for(int i=1;i<=row;i++) {
            for(int j=1;j<=col;j++) {
                if(map[i][j]==-1)
                map[i][j]=map[i-1][j]+map[i][j-1];
            }
        }
        
//        //显示网格状态
//        for(int i=0;i<=row;i++) {
//            for(int j=0;j<=col;j++) {
//                System.out.printf("%3d ", map[i][j]);
//            }
//            System.out.println();
//        }
        System.out.println(map[row][col]);
    }

}

tip:注意数组数据类型,对于测试数据,数组使用int类型会溢出,(洛谷有两个测试项不通过),需使用long类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值