题目描述
小明冒充X星球的骑士,进入了一个奇怪的城堡。
城堡里边什么都没有,只有方形石头铺成的地面。
假设城堡地面是 n x n 个方格。【如图1.png】所示。
按习俗,骑士要从西北角走到东南角。
可以横向或纵向移动,但不能斜着走,也不能跳跃。
每走到一个新方格,就要向正北方和正西方各射一箭。
(城堡的西墙和北墙内各有 n 个靶子)
同一个方格只允许经过一次。但不必走完所有的方格。
如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?
有时是可以的,比如图1.png中的例子。
本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)
输入
第一行一个整数N(0<N<20),表示地面有 N x N 个方格
第二行N个整数,空格分开,表示北边的箭靶上的数字(自西向东)
第三行N个整数,空格分开,表示西边的箭靶上的数字(自北向南)
输出
一行若干个整数,表示骑士路径。
为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号: 0,1,2,3…
比如,图1.png中的方块编号为:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
样例输入
4
2 4 3 4
4 3 3 3
样例输出
0 4 5 1 2 3 7 11 10 9 13 14 15
c语言AC代码
#include <stdio.h>
int n,a[2][25],b[2][25],c[25][25],d[25][25],e[25],count=0;//a用来存放目标箭靶数(输入),b存放走过的路径射中的箭靶数(和a进行对比),c用来标记是否走过,d存放是第几个块
//e存放输出的路径
int dx[4]={0,1,-1,0}; //四个方向
int dy[4]={1,0,0,-1};
int judge1() //判断走过的路径的箭靶数是否与目标相同
{
int i;
for(i=0;i<n;i++)
if(a[0][i]!=b[0][i]||a[1][i]!=b[1][i])
return 0;
return 1;
}
void dfs(int x1,int y1,int step)
{ int i,j;
if(x1==n-1&&y1==n-1) //到达终点
{
if(judge1()==1) //与目标靶数相同
{
for(i=0;i<count;i++) //输出
printf("%d ",e[i]);
}
return ;
}
else {
int m;
for(m=0;m<4;m++)
{
int x2=x1+dx[m];
int y2=y1+dy[m];
if(c[x2][y2]==0&&x2>=0&&x2<n&&y2>=0&&y2<n)//未被走过,在方格内
{
b[0][y2]++; //靶数加一
b[1][x2]++;
c[x2][y2]=step; //等于1也可以,等于step输出可以看出来走的路径
e[count]=d[x2][y2]; //保存路径
count++;
dfs(x2,y2,step+1); //继续往下搜索,回溯
b[0][y2]--;
b[1][x2]--;
c[x2][y2]=0;
e[count]=0;
count--;
}
}
}
}
int main()
{
scanf("%d",&n);
int i,j,cou=0;
for(i=0;i<n;i++)
scanf("%d",&a[0][i]);
for(i=0;i<n;i++)
scanf("%d",&a[1][i]);
for(i=0;i<n;i++) //保存块数
for(j=0;j<n;j++)
{
d[i][j]=cou;
cou++;
}
e[0]=0; //初始化
count++;
c[0][0]=1;
b[0][0]=b[1][0]=1;
dfs(0,0,2);
return 0;
}