P1002 [NOIP2002 普及组] 过河卒

题目描述

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

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

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

输入格式

一行四个正整数,分别表示  点坐标和马的坐标。

输出格式

一个整数,表示所有的路径条数。

#include <iostream>
using namespace std;
long long f[25][25];
bool g[25][25];
// x1为棋盘长度 y1为棋盘宽度
// x2为马的横坐标 y2为马的纵坐标
// g数组记录该点是否可走 f数组记录路线
int main()
{
    int x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    g[x2][y2] = 1;
    //记录马的控制点
    if (x2 > 1 and y2 != 0)
    {
        g[x2 - 2][y2 - 1] = 1;
    } //这里>1与>=2是等效的,下同
    if (x2 < 19 and y2 != 0)
    {
        g[x2 + 2][y2 - 1] = 1;
    } //这里<19与<=18是等效的,下同
    if (x2 > 1 and y2 != 20)
    {
        g[x2 - 2][y2 + 1] = 1;
    }
    if (x2 < 19 and y2 != 20)
    {
        g[x2 + 2][y2 + 1] = 1;
    }
    if (x2 != 0 and y2 > 1)
    {
        g[x2 - 1][y2 - 2] = 1;
    }
    if (x2 != 0 and y2 < 19)
    {
        g[x2 - 1][y2 + 2] = 1;
    }
    if (x2 != 20 and y2 > 1)
    {
        g[x2 + 1][y2 - 2] = 1;
    }
    if (x2 != 20 and y2 < 19)
    {
        g[x2 + 1][y2 + 2] = 1;
    }
    //递推过程
    for (int i = 0; i <= x1; ++i)
    {
        for (int j = 0; j <= y1; ++j)
            if (!g[i][j])
            {                          //该点没被马控制
                if (i == 0 and j == 0) //递推边界1 f[0][0]=1
                {
                    f[0][0] = 1;
                }
                else if (i == 0 and j > 0) //递推边界2,x=0时;
                {
                    f[0][j] = f[0][j - 1];
                }
                else if (i > 0 and j == 0) //递推边界3,y=0时;
                {
                    f[i][0] = f[i - 1][0];
                }
                else
                {
                    f[i][j] = f[i - 1][j] + f[i][j - 1];
                } //递推核心
            }
    }
    //最终i循环到x1位置,j循环到y1位置(x1,y1)即为目标点)则f[x1][y1]就是答案
    cout << f[x1][y1]; //
    return 0;
}

 

posted @ 2022-01-14 15:54  亚托莉的亚托莉  阅读(28)  评论(2)    收藏  举报