P1002 过河卒
题目描述
棋盘上AAA点有一个过河卒,需要走到目标BBB点。卒行走的规则:可以向下、或者向右。同时在棋盘上CCC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,AAA点(0,0)(0, 0)(0,0)、BBB点(n,m)(n, m)(n,m)(nnn, mmm为不超过202020的整数),同样马的位置坐标是需要给出的。
现在要求你计算出卒从AAA点能够到达BBB点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个数据,分别表示BBB点坐标和马的坐标。
输出格式
一个数据,表示所有的路径条数。
输入输出样例
输入 #1
6 6 3 3
输出 #1
6
说明/提示
结果可能很大!
思路:标记🐎的位置和🐎能走到的点建图,与🐎有关的位置点上可走的路线条数一定是0。
根据当前点状态可分为边界状态和非边界状态两种情况。
边界态:当x!=0,y==0时,该点状态dp[x][y]=dp[x-1][y],同理,x==0,y!=0时,dp[x][y]=dp[x][y-1]。
非边界态:当x>0,y>0即走在棋盘内部时,状态dp[x][y]=dp[x-1][y]+dp[x][y-1]。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 25; typedef long long LL; LL dp[maxn][maxn]; LL maze[maxn][maxn]; LL n,m,x,y,ans; int main() { while(scanf("%lld%lld%lld%lld",&n,&m,&x,&y)!=EOF) { memset(maze,0,sizeof(maze)); for(int i=0;i<=n;i++) { for(int j=0;j<=m;j++) { if((i==x&&j==y)) { maze[i][j]=0; } else if(i==x-2&&j==y-1) maze[i][j]=0; else if(i==x-1&&j==y-2) maze[i][j]=0; else if(i==x+1&&j==y-2) maze[i][j]=0; else if(i==x+2&&j==y-1) maze[i][j]=0; else if(i==x-2&&j==y+1) maze[i][j]=0; else if(i==x-1&&j==y+2) maze[i][j]=0; else if(i==x+1&&j==y+2) maze[i][j]=0; else if(i==x+2&&j==y+1) maze[i][j]=0; else maze[i][j]=1; // printf("%d ",maze[i][j]); } //printf("\n"); } //printf("\n"); //memset(dp,0,sizeof(dp)); for(int i=0;i<=n;i++) { for(int j=0;j<=m;j++) { if(maze[i][j]){ if((i==0&&j==0)) continue; else if(i==0) { maze[i][j]=maze[i][j-1]; } else if(j==0) { maze[i][j]=maze[i-1][j]; } else maze[i][j]=maze[i-1][j]+maze[i][j-1]; //printf("dp[%d][%d]:%d\n",i,j,maze[i][j]); } //printf("%d ",maze[i][j]); } // printf("\n"); } printf("%lld\n",maze[n][m]); } return 0; }