题目描述
小明冒充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
这里就是直接dfs,把每个位置对应两个数组的位置减1,看看到达终点的时候是不是两个数组都是0
#include <iostream>
#include <stdlib.h>
using namespace std;
int arr[25][25]={0};
int ans[1005];
int sum=0;
int n;
int mov[5][2]={{1,0},{0,1},{-1,0},{0,-1}};
void dfs(int i, int j){
if(i == n && j == n){//走到终点
int flag=0;
for(int k=1; k<=n; k++){
flag+=arr[k][0];
flag+=arr[0][k];
if(flag>2)//没有进行下去的意义了
break;
}//还有的没走完
if(flag == 2) {//正好走到
for(int k=0; k<sum; k++)
cout<<ans[k]<<" ";
cout<<n*n-1;
}
return ;
}
if(i<1 || i>n || j<1 || j>n)
return ;
if(arr[i][j] != 0)
return ;
if(arr[i][0] <= 0 || arr[0][j] <= 0)//有负数
return ;
arr[i][j]=1;//设为旧点,拔出箭 ,放入答案数组
arr[i][0]--;
arr[0][j]--;
ans[sum++]= (i-1)*n + j - 1 ;
for(int t=0;t<4;t++){
int fx=i+mov[t][0];
int fy=j+mov[t][1];
dfs(fx,fy);
}
sum--;//复原
arr[i][0]++;
arr[0][j]++;
arr[i][j]=0;
return ;
}
int main(){
cin>>n;
for(int i=0; i<n; i++)
cin>>arr[0][i+1];
for(int i=0; i<n; i++)
cin>>arr[i+1][0];
dfs(1,1);//从(1,1)开始走
return 0;
}