这段时间要沉迷刷题一段时间了,就让CSDN陪我一起吧!
一、题目大意
这道题的大致意思就是,给你一个p×q的矩阵,矩阵的行标号为1-p,矩阵的列标号为’A’ - ‘A’ + q,一个骑士要经过这个矩阵的所有格子,他可以从任意一个点开始,并且可以终止于任意点,要求所有可能路径中字典序最小的那条路径。
骑士的行走方式如下:
看着有点类似于象棋中的马。
二、题目思路以及AC代码
这道题也比较简单,一开始我以为是BFS,但后来稍微琢磨了一下,发现直接DFS就可以找到,其实和之前做的POJ 1753, POJ 2965没有什么太大的区别。无非就是DFS遍历加存储成功路径。这里只不过需要在骑士行走的时候,保证一下其字典序最小的问题。
大致思路:
- 因为起始位置不固定,所以要对起始位置进行遍历
- 然后从起始位置开始dfs,注意dfs用到的移动矩阵dx和dy需要特殊设计一下,因为要保证先走字典序小的路径。
下面给出AC代码:
#include <iostream>
#include <stack>
#define MAXN 26
using namespace std;
int p, q;
int dx[8] = { -1, 1, -2, 2, -2, 2, -1, 1 };
int dy[8] = { -2, -2, -1, -1, 1, 1, 2, 2 };
bool map[MAXN][MAXN];
stack<pair<int, int>> s;
void init() {
for (int i = 0; i < MAXN; i++) {
for (int j = 0; j < MAXN; j++) {
map[i][j] = false;
}
}
while (!s.empty()) s.pop();
}
bool dfs(int x, int y, int cnt) {
if (cnt == p*q) return true;
for (int i = 0; i < 8; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (map[nx][ny]) continue;
if (nx < 0 || nx >= p || ny < 0 || ny >= q) continue;
map[nx][ny] = true;
if (dfs(nx, ny, cnt + 1)) {
s.push(make_pair(nx, ny));
return true;
}
map[nx][ny] = false;
}
return false;
}
int main()
{
int T;
cin >> T;
int Case = 0;
while (T--) {
Case++;
cin >> p >> q;
bool flag = false;
for (int j = 0; j < q && !flag; j++) {
for (int i = 0; i < p && !flag; i++) {
init();
map[i][j] = true;
if (dfs(i, j, 1)) {
s.push(make_pair(i, j));
flag = true;
}
}
}
cout << "Scenario #" << Case << ":" << endl;
if (!flag) {
cout << "impossible\n" << endl;
continue;
}
while (!s.empty()) {
pair<int, int> pp = s.top(); s.pop();
cout << (char)(pp.second + 'A') << pp.first + 1;
}
cout << endl << endl;
}
return 0;
}
如果有问题,欢迎大家指正!!!