1.路径之谜
问题描述
小明冒充 X 星球 的骑士,进入了一个奇怪的城堡。城堡里边什么都没有,只有方形石头铺成的地面。假设城堡的地面是 n × n
的方格,如下图所示:

骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走,也不能跳跃。每走到一个新方格,就要向正北方和正西方各射一箭。(城堡的西墙和北墙内各有 n
个靶子)同一个方格只允许经过一次。但不必走完所有的方格。如果只给出靶子上的箭的数目,你能推断出骑士的行走路线吗?有时是可以的,比如上图中的例子。
本题要求已知箭靶上的数字,求骑士的行走路径(测试数据保证路径唯一)。
输入格式
- 第一行一个整数
N
,表示地面有N × N
个方格。 - 第二行
N
个整数,空格分开,表示北边的箭靶上的数字(自西向东)。 - 第三行
N
个整数,空格分开,表示西边的箭靶上的数字(自北向南)。
输出格式
输出一行若干个整数,表示骑士的路径。
为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号:0, 1, 2, 3, ...
例如,上图中的方块编号为:
in
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
输入样例
in
4
2 4 3 4
4 3 3 3
输出样例
out
0 4 5 1 2 3 7 11 10 9 13 14 15
c++代码
cpp
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> a, b;
vector<vector<bool>> path;
vector<int> recoder;
bool sym = false;
void dfs(int i, int j) {
if (sym || i < 0 || i >= n || j < 0 || j >= n || !path[i][j] || b[i] == 0 || a[j] == 0) return;
b[i]--, a[j]--;
recoder.push_back(i * n + j);
path[i][j] = false;
if (i == n - 1 && j == n - 1) {
bool key = true;
for (int i = 0; i < n && key; i++) {
if (a[i] != 0) key = false;
}
for (int i = 0; i < n && key; i++) {
if (b[i] != 0) key = false;
}
if (key) {
sym = true;
for (int i = 0; i < recoder.size(); i++) {
if (i == recoder.size() - 1) cout << recoder[i];
else cout << recoder[i] << " ";
}
}
b[i]++, a[j]++;
recoder.pop_back();
path[i][j] = true;
return;
}
dfs(i + 1, j), dfs(i, j + 1), dfs(i - 1, j), dfs(i, j - 1);
b[i]++, a[j]++;
recoder.pop_back();
path[i][j] = true;
}
int main() {
cin >> n;
a = vector<int>(n), b = vector<int>(n);
path = vector<vector<bool>>(n, vector<bool>(n, true));
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n; i++) cin >> b[i];
dfs(0, 0);
return 0;
}//by wqs
思路解析
这题是暴力DFS题目,每到达一个坐标(i,j)让b[i]和a[j]减一
剪枝条件就是b[i]和a[j]为0,不能再减去的时候,跳出当前dfs。