过河卒
题目描述
棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的。
现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入输出格式
输入格式:
一行四个数据,分别表示B点坐标和马的坐标。
输出格式:
一个数据,表示所有的路径条数。
输入输出样例
输入样例#1:
6 6 3 3
输出样例#1:
6
使用搜索写了一下,发现不好用,比较慢
#include<iostream> #include<algorithm> using namespace std; const int maxn = 21; int go[maxn][maxn]; int dx[]={-2,-1,1,2,2,1,-1,-2}; int dy[]={1,2,2,1,-1,-2,-2,-1}; int n,m; int match(int x,int y) { return x>=0 && x<=n && y>=0 && y<=m && !go[x][y]; } void search(int x,int y,long long &res) { if(x==n && y==m) { res++; return ; } else { if(match(x+1,y)) search(x+1,y,res); if(match(x,y+1)) search(x,y+1,res); } } int main(void) { int x0,y0,x1,y1; cin >> x0 >> y0 >> n >> m; go[x0][y0]=1;//不能走 for(int i=0;i<8;i++) { int newx = x0+dx[i]; int newy = y0+dy[i]; go[newx][newy]=1; } long long res = 0; search(0,0,res); cout << res; return 0; }
这是使用动态规划的方法写的,自己构思的
#include<iostream> #include<algorithm> using namespace std; const int maxn = 21; int go[maxn][maxn]; int dx[]={-2,-1,1,2,2,1,-1,-2}; int dy[]={1,2,2,1,-1,-2,-2,-1}; int n,m,x,y; int dp[maxn][maxn]; int main(void) { cin >> n >> m >> x >> y; go[x][y]=1; for(int i=0;i<8;i++) { int xx = x+dx[i]; int yy = y+dy[i]; go[xx][yy]=1; } dp[0][0]=1; for(int i=1;i<=n;i++) { if(go[i][0]) dp[i][0]=0; else dp[i][0] = dp[i-1][0]; } for(int i=1;i<=m;i++) { if(go[0][i]) dp[0][i]=0; else dp[0][i]=dp[0][i-1]; } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(go[i][j]) dp[i][j]=0; else dp[i][j]=dp[i-1][j]+dp[i][j-1]; } } cout << dp[n][m]; return 0; }
还有一个网上的参考的程序,她的有点在于省略了对于不可走点的计算方便。
#include<iostream> #include<algorithm> using namespace std; const int maxn = 21; int go[maxn][maxn]; int dp[maxn][maxn]; int n,m,x,y; bool ok(int i,int j) { if(i>n || j>m) return 0; if(i==x && j==y) return 0; if(abs(i-x)==2 && abs(j-y)==1) return 0; if(abs(i-x)==1 && abs(j-y)==2) return 0; return 1; } int main(void) { cin >> n >> m >> x >> y; dp[0][0]=1; for(int i=0;i<=n;i++) { for(int j=0;j<=m;j++) { if(ok(i+1,j)) dp[i+1][j]+=dp[i][j]; if(ok(i,j+1)) dp[i][j+1]+=dp[i][j]; } } cout << dp[n][m]; return 0; }