过河卒
题目描述
棋盘上AA点有一个过河卒,需要走到目标BB点。卒行走的规则:可以向下、或者向右。同时在棋盘上CC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,AA点(0, 0)(0,0)、BB点(n, m)(n,m)(nn, mm为不超过2020的整数),同样马的位置坐标是需要给出的。
现在要求你计算出卒从AA点能够到达BB点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个数据,分别表示BB点坐标和马的坐标。
输出格式
一个数据,表示所有的路径条数。
输入:
6 6 3 3
输出:
6
此题有两种写法:
- 深度优先搜索(时间复杂度较高)
根据题意就是统计到某点(n,m)的次数的问题:
代码如下:
#include<stdio.h>
int A[25][25]={0};
int B[2][2]={1,0,0,1};
int m,n,g,l;
int sum=0;
int ave(int x,int y)
{
if(x==n&&y==m)
{
sum++;
return 0;
}
for(int a=0;a<2;a++)
{
if(x+B[a][0]>=0&&x+B[a][0]<=n&& y+B[a][1]>=0 &&y+B[a][1]<=m && A[x+B[a][0]][y+B[a][1]]!=1)
{
ave(x+B[a][0],y+B[a][1]);
}
}
return 0;
}
int main()
{
int a,b,c;
scanf("%d%d%d%d",&n,&m,&g,&l);
A[g][l]=1;
A[g+1][l-2]=1;
A[g+1][l+2]=1;
A[g-1][l-2]=1;
A[g-1][l+2]=1;
A[g+2][l-1]=1;
A[g+2][l+1]=1;
A[g-2][l-1]=1;
A[g-2][l+1]=1;
ave(0,0);
printf("%d\n",sum);
return 0;
}
2.dp 动态规划将每一次的走到的地方标记次数,降低时间复杂度
由于每次都只能向下或向右走,故动态方程为:
dp[i][i] = dp[i-1][j] + dp[i][j-1] ;
dp[i][j] 表示走到点(i,j)的路的个数;
代码如下:
#include<stdio.h>
int main()
{
int a,b,c,m,n,g,l,sum=0;
int A[30][30]={0};
int dp[30][30]={0};
scanf("%d%d%d%d",&n,&m,&g,&l);
dp[0][1]=1;
A[g+1][l+1]=1;
A[g+1+1][l-2+1]=1;
A[g+1+1][l+2+1]=1;
A[g-1+1][l-2+1]=1;
A[g-1+1][l+2+1]=1;
A[g+2+1][l-1+1]=1;
A[g+2+1][l+1+1]=1;
A[g-2+1][l-1+1]=1;
A[g-2+1][l+1+1]=1;
for(a=1;a<=n+1;a++)
for(b=1;b<=m+1;b++)
{
if(A[a][b]!=1)dp[a][b]=dp[a-1][b]+dp[a][b-1];
}
printf("%d\n",dp[n+1][m+1]);
return 0;
}