1219 骑士游历 解答

1219 骑士游历



题目描述 Description

设有一个n*m的棋盘(2≤n≤50,2m≤50),如下图,在棋盘上有一个中国象棋马。

规定:

1)马只能走日字

2)马只能向右跳

问给定起点x1,y1和终点x2,y2,求出马从x1,y1出发到x2,y2的合法路径条数。

1219 骑士游历 解答_第1张图片



输入描述 Input Description

第一行2个整数n和m

第二行4个整数x1,y1,x2,y2

               
输出描述 Output Description

输出方案数

               
样例输入 Sample Input

30 30

1 15 3 15

               
样例输出 Sample Output

2

#include<stdio.h>
#include<string.h>
#include<math.h>
long long a[100][100];

int main()
{
	int i,j,sx,sy,ex,ey,n,m,x,y;
	scanf("%d %d",&n,&m);
	scanf("%d %d %d %d",&sx,&sy,&ex,&ey);
	a[sx][sy]=1;
	for(x=1;x<=n;x++)
	{
		for(y=1;y<=m;y++)
		{//每一步的具体判断,,判断其是否超界 
			if(x-2>=1&&y-1>=1)   a[x][y]+=a[x-2][y-1];
			if(x-1>=1&&y-2>=1)   a[x][y]+=a[x-1][y-2];
			if(x-1>=1&&y+2<=m)   a[x][y]+=a[x-1][y+2];
			if(x-2>=1&&y+1<=m)   a[x][y]+=a[x-2][y+1];
		}
	}
	printf("%lld",a[ex][ey]);//打表,动态规划 
	return 0;
}


第二种解法:


#include<cstdio>
int main()
{
	long long dp[55][55]={0};int n,m,x,y,a,b;
	scanf("%d %d %d %d %d %d",&n,&m,&x,&y,&a,&b);
	dp[x][y]=1;
	for(int i=x+1;i<=n;i++)
		for(int j=1;j<=m;j++)
			dp[i][j]=dp[i-2][j-1]+dp[i-2][j+1]+dp[i-1][j-2]+dp[i-1][j+2];
	printf("%lld",dp[a][b]);
} 

你可能会问,为什么不判断其是否越界,,因为即使其越界了,,因为是二维数组,所以其越界了值也会为0,,这就是为什么其I=x+1而不是从0开始的原因了,而且这也提高了效率!


第三种:  目前没看懂

#include<cstdio>
int n,m,a,b,c,d,vis[55][55],way[4][2]={{2,1},{1,2},{1,-2},{2,-1}}; 
long long f[55][55],need[55][55];
void go(int x,int y)
{
	if(x>=c) return ;
	long long  now=f[c][d];
	if(need[x][y])
	{
		f[c][d]+=need[x][y];
		return;
	}
	for(int i=0;i<4;i++)
		if(x+way[i][0]<=n&&x+way[i][0]>0&&y+way[i][1]<=m&&y+way[i][1]>0&&!vis[x+way[i][0]][y+way[i][1]])
		{	
			vis[x+way[i][0]][y+way[i][1]]=1;
			f[x+way[i][0]][y+way[i][1]]++;
			go(x+way[i][0],y+way[i][1]);
			vis[x+way[i][0]][y+way[i][1]]=0;
		}
	need[x][y]=f[c][d]-now;
}
int main()
{	
	scanf("%d%d%d%d%d%d",&n,&m,&a,&b,&c,&d);
	vis[a][b]=1;
	f[a][b]=1;
	go(a,b);
	printf("%lld",f[c][d]);
	return 0;
}


你可能感兴趣的:(codevs)