A Knight's Journey
Description
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.
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 附上详细解释: #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <cstdlib> #include <queue> #include <iomanip> using namespace std; #define maxn 40 struct node{ int x,y; }num[maxn]; int visit[maxn][maxn]; int p,q; int dr[8]= {-1,1,-2,2,-2,2,-1,1};/走的是日字形,并且要按照字典序,这个顺序不能乱改,否则会出错 int dc[8]= {-2,-2,-1,-1,1,1,2,2};//因为是按字典序排序,因为字符的输出是按照纵坐标的位置来输出的,所以我们要把纵坐标从小到大排序,那么第一个得到的必定是字符最小的那个 /********************* A B C D 1 2 3 4 **********************/ bool flag; void dfs(int m,int n,int cur) { if(flag) return;//如果找到我们就要返回,为什么我要讲这一点呢?因为如果这个不写的话,那么flag为1时,将往下继续执行语句,那么//num[cur].x=m;//此时的cur值并未发生变化,而是回到了上一个的dfs去了 // num[cur].y=n//我们所记录的路径就被更新了,得到的答案肯定是错的 if(cur==p*q)//如果所有的点我们都已经遍历过了,自然准备结束了 { num[cur].x=m;//结束时,该点的行 num[cur].y=n;//结束时,该点的列 flag=1;//标记,我们找到了这样的路径 return; } num[cur].x=m;//如果点还未遍历完,我们要把所走过的点的路径记录下来 num[cur].y=n; for(int i=0;i<8;i++) { int r=m+dr[i]; int c=n+dc[i]; if(r>=1 && r<=p && c>=1 && c<=q && visit[r][c]==0) { visit[r][c]=1; dfs(r,c,cur+1); visit[r][c]=0;//因为具体的哪条路能过完全走完我们不确定,那么每条路都要试试,所以我们要进行回溯 } }}int main(){ int t,i,j,k=1; cin>>t; while(t--) { cin>>p>>q; flag=0; memset(visit,0,sizeof(visit)); for(i=1;i<=p;i++) { for(j=1;j<=q;j++) { if(flag) break;//如果搜到了,我们马上跳出循环 visit[i][j]=1;//先标记起点 dfs(i,j,1);//进行搜索,如果搜索结束,进行下一循环 visit[i][j]=0;//回溯 } if(flag) break;//如果搜到了,我们马上跳出循环 } cout<<"Scenario #"<<k++<<":"<<endl; if(!flag) { cout<<"impossible"<<endl; }else{ for(i=1;i<=p*q;i++) { printf("%c%d",num[i].y+'A'-1,num[i].x);//国际象棋是行为数字,列为字母 } cout<<endl; } cout<<endl;//特别是这里有点小坑,容易漏掉 } return 0; }