A Knight's Journey
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 18559 | Accepted: 6240 |
Description

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.
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
题目连接:http://poj.org/problem?id=2488
算法类型:DFS&&回溯。
解题思路:这是一个DFS加回溯的问题,想了几天,代码修改过N次,最终AC.....主要问题就是回溯的执行和递归的调用,还有注意要字典序输出和行是字母 列是数字。算法实现:#include<stdio.h> #include<string.h> #include<stdlib.h> int dx[8]={-2,-2,-1,-1,1,1,2,2}; //这是字典序的方向数组; int dy[8]={-1,1,-2,2,-2,2,-1,1}; int way[100][100]; //用来记录走过的位置; int vis[100][100]; //记录是否搜索过; int p,q; int DFS(int tot,int real,int x,int y) //深搜函数; { int i,nx,ny; if(real==tot) //如果走过的步数等于棋盘总数,函数返回1,调用结束; return 1; else { for(i=0;i<8;i++) //依次按照字典序的优先方向走; { nx=x+dx[i],ny=y+dy[i]; //下一步的坐标; if(nx>=0 && nx<q && ny>=0 && ny<p && !vis[nx][ny]) //判断是否在棋盘内,是否被访问过; { vis[nx][ny]=1; //标记为已访问; if(DFS(tot,real+1,nx,ny)) //在判断语句中递归调用,在最后一个调用的函数中获得函数返回值; { way[real][0]=nx,way[real][1]=ny; //在搜索成功后记录走过的的坐标,并返回给1,让上一步的递归调用继续运行; return 1; } vis[nx][ny]=0; //回溯,如果不能找到下一步的路径,函数返回给0,并进入上一个递归函数的if语句,进行下一个字典序搜索; } } } return 0; } int main() { int n; scanf("%d",&n); int i,j; for(i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); //吧vis全部置为0; vis[0][0]=1; scanf("%d%d",&p,&q); printf("Scenario #%d:\n",i); if(DFS(q*p,1,0,0)) { for(j=0;j<q*p;j++) { printf("%c",way[j][0]+'A'); //输出函数; printf("%d",way[j][1]+1); } } else { printf("impossible"); } if(i!=n) printf("\n\n"); } return 0; }