Day2-F-A Knight's Journey POJ-2488

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

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

Input

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

Output

The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the lexicographically first path that visits all squares of the chessboard with knight moves followed by an empty line. The path should be 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.

Sample Input

3
1 1
2 3
4 3

Sample Output

Scenario #1:
A1

Scenario #2:
impossible

Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4

简述:给你一副p*q的棋盘,求出每个点恰好只走一次的路径,若有多个答案输出字典序最小的。
分析:求最深路径,只经过一次,DFS+回溯,注意到如果其能满足题意,那么必然会经过A1,从A1开始字典序最小,所以从A1开始DFS搜索即可,注意保证dx与dy也是字典序排序,代码如下:
const int maxm = 30;
//注意字典序大小排序
const int dx[] = {-1, 1, -2, 2, -2, 2, -1, 1}; 
const int dy[] = {-2, -2, -1, -1, 1, 1, 2, 2};

int vis[maxm][maxm], Next[maxm][maxm], r, c, n, kase = 0;

bool inside(int x,int y) {
    return x > 0 && x <= r && y > 0 && y <= c;
}

void print(int x,int y,int t) {
    if(t) {
        printf("%c%d", y - 1 + 'A', x);
        print(Next[x][y] / 10, Next[x][y] % 10, t - 1);
    }
}

bool dfs(int x,int y,int t) {
    vis[x][y] = 1;
    if(t == r * c) {
        return true;
    }
    for (int i = 0; i < 8; ++i) {
        int nx = x + dx[i], ny = y + dy[i];
        if(inside(nx,ny) && !vis[nx][ny]) {
            Next[x][y] = nx * 10 + ny;
            if(dfs(nx, ny,t+1)) {
                return true;
            }
        }
    }
    vis[x][y] = 0;
    return false;
}

int main() {
    scanf("%d", &n);
    while(n--) {
        scanf("%d%d", &r, &c);
        memset(vis, 0, sizeof(vis)), memset(Next, 0, sizeof(Next));
        printf("Scenario #%d:
", ++kase);
        if(dfs(1, 1, 1)) {
            print(1,1,r*c);
        } else {
            printf("impossible");
        }
        printf("

");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/GRedComeT/p/11221348.html