马拦过河卒(C++)

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

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

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

Input Format

一行四个正整数,分别表示 B 点坐标和马的坐标。对于 100% 的数据,1≤n,m≤20,0≤马的坐标≤20。

Output Format

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

Input Example

6 6 3 3

Output Example

6

题解思路:

二维数组中a[i][j]的值存储从坐标为(i,j)的点到B点(终点)的所有路径数。

从二维数组右下方向左上方开始逐行逐列扫描并赋值。

状态转移方程:a[i][j]=a[i][j+1]+a[i+1][j]。

初始化:a[n-1][m]和a[n][m-1]值为1,因为它们到终点a[n][m]都只能有一条路

边界处理:二维数组中第n行和第m列上各数组元素的值为1,因为它们到终点也都只有一条路。

特殊条件处理:

a[i][j+1]和a[i+1][j]都是马能一步到达的位置时则将a[i][j]=max。

a[i][j+1]是马能一步到达的位置时则a[i][j]=a[i+1][j]。

a[i+1][j]是马能一步到达的位置时则a[i][j]=a[i][j+1]。

AC代码:

#include
#include
#define maxn 10000  //马占有的地方以及能一步到的地方赋为10000
using namespace std;
int main()
{
    int n,m;long int a[21][21];int xm,ym;//xm,ym表示马的坐标
    memset(a,0,sizeof(a));//二维数组元素初始化为0
    cin>>n>>m>>xm>>ym;
    a[xm][ym]=maxn;//马占有的地方赋为maxn
    int i,j;
    for(j=ym-1;j<=ym+1;j+=2)//马能一步到达的坐标赋为maxn
        for(i=xm-2;i<=xm+2;i+=4)
        {
            if(i<0||j<0)
                continue;
            else
                a[i][j]=maxn;  
        }
    for(i=xm-1;i<=xm+1;i+=2)//处理马能一步到达的坐标赋为maxn
        for(j=ym-2;j<=ym+2;j+=4)
        {
            if(i<0||j<0)
                continue;
            else
                a[i][j]=maxn;
        }

    for(i=n;i>=0;i--)
        for(j=m;j>=0;j--)
        {
            if(a[i][j]==maxn)//马占有的地方不用赋值了
                continue;
            if(i==n||j==m)//边界处理,由于卒只能往右,往下走,此边界只有一条路
                a[i][j]=1;
            else if(a[i][j+1]==maxn&&a[i+1][j]==maxn)
                a[i][j]=maxn;
            else if(a[i][j+1]==maxn&&a[i+1][j]!=maxn)
                a[i][j]=a[i+1][j];
            else if(a[i][j+1]!=maxn&&a[i+1][j]==maxn)
                a[i][j]=a[i][j+1];
            else
                a[i][j]=a[i][j+1]+a[i+1][j];//正常情况
        }
cout<

 

你可能感兴趣的:(数据结构与算法)