A Knight's Journey
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 33825 | Accepted: 11521 |
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, . . .
(输入的第一行是一个整数,代表测试样例数目。每个样例包含两个整数(1~26之间)p用数字代表,q用 大写字母代表。)
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.
(第一行输出
"Scenario #i:",i代表第i组测试数据。 第二行输出按照字典序排序的第一条路径,第三行输出换行)
Sample Input
3 1 1 2 3 4 3
Sample Output
Scenario #1: A1 Scenario #2: impossible Scenario #3: A1B3C1A2B4C2A3B1C3A4B2C4
题解:简单的一道DFS题目,按照字典序小到大去遍历整个棋盘,用栈保存路径,当找到第一条合适的路径便输出栈里的内容即可。
#include<iostream> #include<string> #include<stack> using namespace std; int p,q; bool visited[27][27];//访问位数组,true表示已经访问 int px[]={-1,1,-2,2,-2,2,-1,1};//顺序不能乱,按照字典序小到大推算而得 int py[]={-2,-2,-1,-1,1,1,2,2}; struct loc{ //坐标点 int x; int y; loc(int x,int y){ this->x=x; this->y=y; } }; stack<loc> s; //栈,用来保存路径 bool dfs(int x,int y,int step){ s.push(loc(x,y)); //将路径入栈,置访问位 visited[x][y]=true; if(step==p*q) return true; //路径符合要求,则返回true
for(int i=0;i<8;i++) { //从点(x,y),向周围八个方向尝试转移 int nx=x+px[i],ny=y+py[i]; if(0<=nx && nx<p && ny>=0 &&ny<q && !visited[nx][ny]) if (dfs(nx,ny,step+1)) return true; } s.pop(); //恢复现场 visited[x][y]=false; return false; //(x,y)这个点不符合要求 }
void printPath() //输出路径 { if(s.empty()) return ; loc temp=s.top(); s.pop(); printPath(); cout<<(char)(temp.y+'A')<<temp.x+1; }
int main(){ int n; cin>>n; for(int i=0;i<n;i++){ cin>>p>>q; cout<<"Scenario #"<<i+1<<":"<<endl; bool getPath=false; for(int j=0;j<q;j++) for(int k=0;k<p;k++){ memset(visited,0,sizeof(visited)); if(dfs(k,j,1)) { printPath(); getPath=true; goto part; } } part: if(!getPath) cout<<"impossible"; cout<<endl<<endl; } return 0; }