A Knight's Journey
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 49498 | Accepted: 16787 |
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
///深度搜索和回溯思想,还有字典顺序输出
///一个骑士,在p*q棋盘上以一个方向走两格,再垂直走一格的方式走遍每一个格子
#include<iostream>
#include<cstring>
using namespace std;
int vis[30][30],m,n,book[60][2];//vis用于标记走过的位置,book用于记录当前位置
int step[8][2]={{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}};//枚举出骑士走的方向,但要注意字典序,所以方向的陈列是有顺序的
bool flag=0;//作为找到答案的标志
void dfs(int x,int y,int t)
{
if(t==(m*n))//判断是否所有格子均被遍历过
{
flag=1;
return;
}
if(flag==1) return; //因为是按照字典序进行查找的,一旦找到即为答案就直接返回
for(int i=0;i<8;i++) //遍历八个方向
{
int tx=x+step[i][0];//下一步x
int ty=y+step[i][1];//下一步y(顺序很重要不要弄错)
if(vis[tx][ty]==1)
{
vis[tx][ty]=0; //走过的格子就不能再走,所以被标记为0
book[t][0]=tx; //记录当前格子
book[t][1]=ty;
dfs(tx,ty,t+1); //继续搜索
if(flag==1) //若已找到答案,跳出循环
break;
else
vis[tx][ty]=1; //若此路不通,则将当前格子回溯(回溯过程的还原)
}
}
return;
}
void print()
{
for(int i=0;book[i][1]!=0;i++)
{
cout<<(char)(book[i][1]-1+'A')<<book[i][0];
}
cout<<endl;
return;
}
int main()
{//i不能设为全局变量
int x;
cin>>x;
for(int i=1;i<=x;i++)
{
flag=0; //flvisg用于记录是否找到走完全图的最小字典序路径
memset(vis,0,sizeof(vis));
memset(book,0,sizeof(book));
cin>>m>>n;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
vis[i][j]=1; //标记图中走的地方
vis[1][1]=0;
dfs(1,1,1);//3个参数,x,y为当前位置坐标,t为已经走过的格子数
book[0][0]=1;
book[0][1]=1;
cout<<"Scenario #"<<i<<":"<<endl;
if(flag==1)
{
print();//输出结果
}
else
cout<<"impossible"<<endl;//不存在就输出impossible
cout<<endl;
}
}