【DFS】POJ 2488 A Knight's Journey

这段时间要沉迷刷题一段时间了,就让CSDN陪我一起吧!

一、题目大意

这道题的大致意思就是,给你一个p×q的矩阵,矩阵的行标号为1-p,矩阵的列标号为’A’ - ‘A’ + q,一个骑士要经过这个矩阵的所有格子,他可以从任意一个点开始,并且可以终止于任意点,要求所有可能路径中字典序最小的那条路径。

骑士的行走方式如下:
在这里插入图片描述
看着有点类似于象棋中的马。

二、题目思路以及AC代码

这道题也比较简单,一开始我以为是BFS,但后来稍微琢磨了一下,发现直接DFS就可以找到,其实和之前做的POJ 1753, POJ 2965没有什么太大的区别。无非就是DFS遍历加存储成功路径。这里只不过需要在骑士行走的时候,保证一下其字典序最小的问题。

大致思路:

  1. 因为起始位置不固定,所以要对起始位置进行遍历
  2. 然后从起始位置开始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;
}

如果有问题,欢迎大家指正!!!

猜你喜欢

转载自blog.csdn.net/m0_38055352/article/details/92013018