POJ2488==DFS+路径输出+字典序排列

/*
 * POJ 2488
 * DFS进行遍历就好,记录走过的路径,只要不重复地走过p*q个方格就行了(结束条件) 
 *
/*
 这里注意几个问题:
 1、国际象棋,横着是字母,竖着是数字。
 2、是按字典序输出的,所以搜索方向上一定要注意!这里是个坑。 
 3、忽略“The knight can start and end on any square of the board.”这句话,这也
    算是个坑,实际上只要从A1点开始搜索就可以了,只要能从A1开始能搜到一条遍历全棋盘
	的路径,那么肯定从棋盘上的任意一个点作为起点都能搜出一条遍历棋盘的路径,并且题目
	要求要按字典序输出,所以只需从起点开始搜索就可以了!

*/

#include
#include
#include
#include
using namespace std;
const int maxn = 50;
int dirx[] = {-2, -2, -1, -1, 1, 1, 2, 2}; 
int diry[] = {-1, 1, -2, 2, -2, 2, -1, 1};
int N, R, C, vis[maxn][maxn];
bool ans;
struct node{
	int x, y;
	node(int _x=0, int _y=0):x(_x), y(_y){}
}path[maxn*maxn];

void Print() {
	for(int i = 1; i <= N; i++) {
		cout << char(path[i].x+64) << path[i].y;
	}
	cout << endl;
}

bool dfs(int cur, int x, int y) {
	if(cur == N) return true;
	for(int i = 0; i < 8; i++) {
		int tx = x + dirx[i];
		int ty = y + diry[i];
		if(tx<=R && tx >=1 && ty <= C && ty >= 1 && !vis[tx][ty]) {
			vis[tx][ty] = 1;
			path[cur+1] = node(tx, ty);
			if(dfs(cur+1, tx, ty)) return true;
			vis[tx][ty] = 0;
		}
	}
	return false;
}

int main() {
	int T;
	cin >> T;
	int cas = 0;
	while(T--) {
		ans = false;
		cin >> C >> R;
		N = R*C;
		memset(vis, 0, sizeof(vis));
		vis[1][1] = 1;
		path[1] = node(1, 1);
		ans = dfs(1, 1, 1);
		cout << "Scenario #" << ++cas << ":" << endl;
		if(ans) Print();
		else cout << "impossible" << endl;
		if(T) cout << endl;
	} 
	return 0;
}

//AC


你可能感兴趣的:(POJ2488==DFS+路径输出+字典序排列)