78. [NOIP2002] 过河卒
★ 输入文件:pj024.in
输出文件:
pj024.out
简单对比
时间限制:1 s 内存限制:128 MB
问题描述
如图,A点有一过河卒,需要走到目标B点。卒行走的规则:可以向下,或者向右。
同时在棋盘上的任一点有一个对方的马(如图中C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。
例如上图C点的马可控制9个点(P1...P8,C)。卒不能通过对方马的控制点。棋盘用坐标表示,A点(0,0),B点(n,m)(n,m为不超过20的整数,并有键盘输入),同样,马的位置坐标是需要给出的(约定:C≠A同时C≠B)。
现在要你计算出 卒从A点出发能够到达B点的路径的条数。
【输入格式】
输入
一行四个整数n,m,x,y
B点坐标(n,m)以及对马的坐标(x,y){不用判错}
【输出格式】
输出
一个整数(路径的条数)
【输入样例】
输入文件
6 6 3 2
输出文件
17
#include <iostream>
#include <cstdio>
using namespace std;
#define MAX_N 21
int n,m,x,y;
int dp[MAX_N][MAX_N];
int dx[]={2,1,2,-1,-2,1,-1,-2};
int dy[]={1,2,-1,2,1,-2,-2,-1};
bool no[MAX_N][MAX_N];
int main()
{
freopen("pj024.in","r",stdin);
freopen("pj024.out","w",stdout);
cin>>n>>m>>y>>x;
for(int i=0;i<8;i++)
{
int nx=x+dx[i],ny=y+dy[i];
if(nx>=0 && nx<=m && ny>=0 && ny<=n)
{
no[ny][nx]=true;
}
}
no[y][x]=true;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
if(no[i][j]) continue;
int cnt=0;
if(i>=1 && !no[i-1][j]) cnt+=dp[i-1][j];
if(j>=1 && !no[i][j-1]) cnt+=dp[i][j-1];
dp[i][j]=cnt;
if(i==0 && j==0) dp[0][0]=1;
}
}
cout<<dp[n][m]<<endl;
return 0;
}