POJ 2488 A Knight's Journey【dfs】

版权声明:本文为博主原创文章,转载请注明出处,谢谢。 https://blog.csdn.net/nailnehc/article/details/50359575

A Knight's Journey

Time Limit: 1000MS

 

Memory Limit: 65536K

Total Submissions: 37342

 

Accepted: 12683

Description

Background
The knight is getting bored of seeing the same black and white squares againand again and has decided to make a journey
around the world. Whenever a knight moves, it is two squares in one directionand one square perpendicular to this. The world of a knight is the chessboardhe is living on. Our knight lives on a chessboard that has a smaller area thana regular 8 * 8 board, but it is still rectangular. Can you help thisadventurous knight to make travel plans?

Problem
Find a path such that the knight visits every square once. The knight can startand end on any square of the board.

Input

Theinput begins with a positive integer n in the first line. The following linescontain n test cases. Each test case consists of a single line with twopositive integers p and q, such that 1 <= p * q <= 26. This represents ap * q chessboard, where p describes how many different square numbers 1, . . ., p exist, q describes how many different square letters exist. These are thefirst q letters of the Latin alphabet: A, . . .

Output

Theoutput for every scenario begins with a line containing "Scenario#i:", where i is the number of the scenario starting at 1. Then print asingle line containing the lexicographically first path that visits all squaresof the chessboard with knight moves followed by an empty line. The path shouldbe given on a single line by concatenating the names of the visited squares.Each square name consists of a capital letter followed by a number.
If no such path exist, you should output impossible on a single line.

SampleInput

3
1 1
2 3
4 3


SampleOutput

Scenario #1:
A1
 
Scenario #2:
impossible
 
Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4

题目大意:有n个案例,每个案例输入一行,每行两个正整数,代表棋盘的规模,然后你可以从任意一格开始,问:骑士能否在每个格子只走一次的情况下把棋盘上的每个格子都走一遍,如果不行,输出impossible,如果可以,输出所走格子顺序,要求所输出的结果字典序最小,【骑士行走的规则与国际象棋中的规则一样,且棋盘中行号为数,列号为大写英文字母】。

解析:因为要求字典序最小,所以每次都从A1开始就可以了,然后要注意骑士走到附近格子的先后顺序,然后进行深搜就行。

dx[]= {-1, 1, -2, 2, -2, 2, -1, 1};

dy[]= {-2, -2, -1, -1, 1, 1, 2, 2};

 

已Accept代码

#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

struct Node {
	int a, b;
	Node(){}
	Node(int a, int b): a(a), b(b) {};
};

int n, m, total, q = 1;
int dx[] = {-1, 1, -2, 2, -2, 2, -1, 1};
int dy[] = {-2, -2, -1, -1, 1, 1, 2, 2};
int vis[28][28];
bool ok;
vector <Node > Q;

void dfs(int x, int y, int sum) {
	if(x <= 0 || x > n || y <= 0 || y > m || vis[x][y])
		return ;
	vis[x][y] = 1;
	Q.push_back(Node(x, y));
	if(total == sum + 1) {
		ok = true;
		return ;
	}
	for(int i = 0; i < 8; i++) {
		int fx = dx[i] + x;
		int fy = dy[i] + y;
		dfs(fx, fy, sum + 1);
		if(ok)
			return ;
	}
	vis[x][y] = 0;
	Q.pop_back();
}

void Print() {
	printf("Scenario #%d:\n", q++);
	for(int i = 0; i < total; i++) {
		char k = Q[i].b - 1 + 'A';
		printf("%c%d", k, Q[i].a);
	}
	printf("\n");
}

int main() {
	int T;
	scanf("%d", &T);
	while(T--) {
		Q.clear();
		ok = false;
		scanf("%d%d", &n, &m);
		memset(vis, 0, sizeof(vis));
		total = n * m;
		dfs(1, 1, 0);
		if(ok)
			Print();
		else
			printf("Scenario #%d:\nimpossible\n", q++);
		if(T != 0)
			printf("\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/nailnehc/article/details/50359575