A Knight's Journey
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 33825 | Accepted: 11521 |
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, . . .
(输入的第一行是一个整数,代表测试样例数目。每个样例包含两个整数(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; }