路径之谜
题目描述
小明冒充 XX 星球的骑士,进入了一个奇怪的城堡。
城堡里边什么都没有,只有方形石头铺成的地面。
假设城堡地面是 n×nn×n 个方格。如下图所示。
按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走,也不能跳跃。每走到一个新方格,就要向正北方和正西方各射一箭。(城堡的西墙和北墙内各有 nn 个靶子)同一个方格只允许经过一次。但不必走完所有的方格。如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?有时是可以的,比如上图中的例子。
本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)
输入描述
第一行一个整数 NN (0≤N≤200≤N≤20),表示地面有 N×NN×N 个方格。
第二行 NN 个整数,空格分开,表示北边的箭靶上的数字(自西向东)
第三行 NN 个整数,空格分开,表示西边的箭靶上的数字(自北向南)
输出描述
输出一行若干个整数,表示骑士路径。
为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号: 0,1,2,3 ⋯⋯
比如,上图中的方块编号为:
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
好久没写都有点生疏,调试了很久。
#include <iostream>
using namespace std;
int n, top[25], left1[25], map[25][25];
int res[800][2], idx = 0, flag = 0, started = 0;
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
void dfs(int cur_row, int cur_col){
//cout<<cur_row<<" "<<cur_col<<endl;
if(flag == 1){
//cout<< "flag == 1"<<endl;
return ;
}
if(cur_row < 1 || cur_row > n || cur_col < 1 || cur_col > n){
//cout<< "out of bound"<<endl;
return ;
}
if(map[cur_row][cur_col] > 1){
return ;
}
int cnt = 0;
for(int i=1; i<=n; i++){
//cout<<top[i] <<" "<< left1[i]<<endl;
if(top[i] < 0 || left1[i] < 0){
//cout<< "negative num"<<endl;
return ;
}
cnt += top[i] + left1[i];
}
if(cur_row == n && cur_col == n && cnt == 0){
//cout<< "yes"<<endl;
flag = 1;
return ;
}
for(int i=0; i<4; i++){
res[idx][0] = cur_row;
res[idx][1] = cur_col;
left1[cur_row + dir[i][0]]--;
top[cur_col + dir[i][1]]--;
map[cur_row + dir[i][0]][cur_col + dir[i][1]] += 1;
idx++;
dfs(cur_row + dir[i][0], cur_col + dir[i][1]);
if(flag == 1){
//cout<<"yes--"<<endl;
return ;
}
left1[cur_row + dir[i][0]]++;
top[cur_col + dir[i][1]]++;
map[cur_row + dir[i][0]][cur_col + dir[i][1]] -= 1;
idx--;
}
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++){
cin>>top[i];
}
for(int i=1; i<=n; i++){
cin>>left1[i];
}
map[1][1] = 1;
left1[1]--;
top[1]--;
dfs(1, 1);
for(int i=0; i<idx; i++){
int num = ( res[i][0] - 1 ) * n + res[i][1] - 1;
cout<<num<<" ";
}
cout<< n * n - 1;
return 0;
}