过河卒(Noip2002)

【题目描述】
棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上的某一点有一个对方的马(如C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点,如图3-1中的C点和P1,……,P8,卒不能通过对方马的控制点。棋盘用坐标表示,A点(0,0)、B点(n, m) (n,m为不超过20的整数),同样马的位置坐标是需要给出的,C≠A且C≠B。现在要求你计算出卒从A点能够到达B点的路径的条数。



【输入】
给出n、m和C点的坐标。

【输出】
从A点能够到达B点的路径的条数。

【输入样例】
8 6 0 4
【输出样例】
1617
#include <bits/stdc++.h>

using namespace std;

int long long f[25][25],d[25][25];

void aa(int x,int y)   //这个函数用来判断马的控制点是否会越界
{
    int i,j,k;
    if(x<0 || x>20 || y<0 || y>20)
        return;
    else d[x][y]=1;

}

int main()
{
   int n,m,x,y;
   int i,j;
   cin>>n>>m>>x>>y;

    aa(x-1,y+2);
    aa(x+1,y+2);
    aa(x-2,y+1);
    aa(x+2,y+1);
    aa(x-2,y-1);
    aa(x+2,y-1);
    aa(x-1,y-2);
    aa(x+1,y-2);
    aa(x,y);

    f[0][0]=1;   //一开始什么都不走也是1种走法,有种递推的边界的感觉
for(i=0;i<=n;i++) //从行列循环遍历所有的走法 for(j=0;j<=m;j++) { if(d[i][j]==0&&i>0&&j>0) //若此点不是马的控制点而且i,j存在的情况 { f[i][j]=f[i-1][j]+f[i][j-1]; } else if(d[i][j]==1) //这是此点是马的控制点的情况 f[i][j]=0; else if(i>0&&d[i][0]==0) //这是y=0并且此点不是马的控制点的情况就只有一种走法 f[i][0]=f[i-1][0]; else if(j>0&&d[0][j]==0) //同上 f[0][j]=f[0][j-1]; } cout<<f[n][m]<<endl; return 0; }

根据加法原理,到达某一点的路径数目,等于到达其相邻的上点和坐点的路径数目之和。
所以得到递推公式:
f[i][j]=f[i-1][j]+f[i][j-1]
别忘了用long long

posted @ 2018-12-05 22:11  RAIN-code  阅读(843)  评论(0编辑  收藏  举报