B - DFS A Knight's Journey

题目

背景
骑士无聊一次又一次看到相同的黑白方块,因此决定
环游世界。每当骑士移动时,它在一个方向上是两个正方形,而垂直于此方向的正方形则是一个正方形。骑士的世界就是他赖以生存的棋盘。我们的骑士生活在棋盘上,棋盘的面积比普通的8 * 8棋盘小,但它仍然是矩形的。您可以帮助这个冒险的骑士制定旅行计划吗?

问题
找到一条路径,使骑士可以拜访每个广场一次。骑士可以在棋盘的任何正方形上开始和结束。

输入

输入在第一行中以正整数n开头。以下各行包含n个测试用例。每个测试用例都由一条带有两个正整数p和q的单行组成,因此1 <= p * q <=26。这表示一个p * q棋盘,其中p描述了多少个不同的平方号1,。。。,p存在,q描述存在多少个不同的正方形字母。这些是拉丁字母的前q个字母:A 、。。。

输出

每个方案的输出都从包含“Scenario #i:”的行开始,其中i是从1开始的方案编号。然后打印一行,按字典顺序,第一个路径通过骑士移动来访问棋盘的所有正方形用空行。应通过合并访问的正方形的名称在一行上给出路径。每个正方形名称均由大写字母后跟数字组成。
如果不存在这样的路径,则应在单行上输出"impossible"。
(绝对不会告诉你这是机翻)

样例输入

3
1 1
2 3
4 3

样例输出

Scenario #1:
A1

Scenario #2:
impossible

Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~分 ~ 割 ~ 线 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

思路:

数据就8*8,可以搜索。(标题里不写了吗)

一、

首先可以明确,这是跳马问题。所以,路径先写好。

long long gx[20]={-1,1,-1,1,-2,2,-2,2},gy[20]={-2,-2,2,2,-1,-1,1,1};
然后…就开始愉快地打dfs了。
void dfs(long long x,long long y,long long fl)//x,y是当前的行,列。fl记录当前走过多少格子。
{
	a[fl]=y;
	b[fl]=x;//记录路径
	if (fl==n*m)
	{
		flag=1;//如果fl等于格子数,说明走完了。flag记录找到答案。
		return;
	}
	for (int i=0;i<8;i++)
	{
		long long x1=x+gx[i],y1=y+gy[i];
		if (x1>0 && x1<=n && y1>0 && y1<=m && !c[x1][y1] && !flag)//如果没越界,且没走过,并且答案没找到
		 {
		 	c[x1][y1]=1;//记录这个点找过了
		 	dfs(x1,y1,fl+1);
		 	c[x1][y1]=0;//回朔
		 }
	}
}

补完主程序,就完工了。(然而事实并没有这么简单)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
long long gx[20]={-1,1,-1,1,-2,2,-2,2},gy[20]={-2,-2,2,2,-1,-1,1,1};
long long n,m,i,j,k,l,o,p,a[100],b[100],c[50][50],nmsl;
long long flag;
void dfs(long long x,long long y,long long fl)
{
	a[fl]=y;
	b[fl]=x;
	if (fl==n*m)
	{
		flag=1;
		return;
	}
	for (int i=0;i<8;i++)
	{
		long long x1=x+gx[i],y1=y+gy[i];
		if (x1>0 && x1<=n && y1>0 && y1<=m && !c[x1][y1] && !flag)
		 {
		 	c[x1][y1]=1;
		 	dfs(x1,y1,fl+1);
		 	c[x1][y1]=0;
		 }
	}
}
int main()
{
	int T;
	scanf("%lld",&T);
	while (T--)
	 {	
	  	flag=0;
	 	scanf("%lld%lld",&n,&m);
	 	nmsl++;
	 	printf("Scenario #%lld:\n",nmsl);
	 	memset(c,0,sizeof(c));
	 	c[1][1]=1;
	 	dfs(1,1,1);
	 	if (!flag) printf("impossible");
	 	 else
	 	  for (i=1;i<=n*m;i++)
	 	   cout<<char(a[i]+'A'-1)<<b[i];
	 	cout<<"\n";
	 	if (T!=0) cout<<"\n";

	 }
}

结果,输出是

最后几位貌似错了。。。
在这里插入图片描述
再看看输出描述

字典顺序。。。

看样子是要在gx和gy上做点手脚了。

long long gx[20]={-1,1,-2,2,-2,2,-1,1},gy[20]={-2,-2,-1,-1,1,1,2,2};

改完应该能过了。。。
在这里插入图片描述
过了。

完整代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
long long gx[20]={-1,1,-2,2,-2,2,-1,1},gy[20]={-2,-2,-1,-1,1,1,2,2};
long long n,m,i,j,k,l,o,p,a[100],b[100],c[50][50],nmsl;
long long flag;
void dfs(long long x,long long y,long long fl)
{
	a[fl]=y;
	b[fl]=x;
	if (fl==n*m)
	{
		flag=1;
		return;
	}
	for (int i=0;i<8;i++)
	{
		long long x1=x+gx[i],y1=y+gy[i];
		if (x1>0 && x1<=n && y1>0 && y1<=m && !c[x1][y1] && !flag)
		 {
		 	c[x1][y1]=1;
		 	dfs(x1,y1,fl+1);
		 	c[x1][y1]=0;
		 }
	}
}
int main()
{
	int T;
	scanf("%lld",&T);
	while (T--)
	 {	
	  	flag=0;
	 	scanf("%lld%lld",&n,&m);
	 	nmsl++;
	 	printf("Scenario #%lld:\n",nmsl);
	 	memset(c,0,sizeof(c));
	 	c[1][1]=1;
	 	dfs(1,1,1);
	 	if (!flag) printf("impossible");
	 	 else
	 	  for (i=1;i<=n*m;i++)
	 	   cout<<char(a[i]+'A'-1)<<b[i];
	 	cout<<"\n";
	 	if (T!=0) cout<<"\n";

	 }
}

不能用万能头。。。

猜你喜欢

转载自blog.csdn.net/qq_46070004/article/details/103723169