A Knight's Journey
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 21377 | Accepted: 7224 |
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
package poj; import java.util.Scanner; import java.util.Stack; /** * @description 北京大学 OJ 2488: 骑士旅行问题。马走日。 * @technique 递归, 回溯算法。深度优先搜索。 * @version 1.3 * @date 20120802 * @time 13:57 * @author Alex * @note 经过了一上午的奋斗。 最后终于在查看了资料的情况下写出来了。这个版本完全独立于 * 前三个版本。前三个版本真是错的离谱。但是经过上午几百行的的程序,现阶段内部私有类用的驾 * 轻就熟了。。。。 * @result AC */ public class Poj2488_20120802_3 { private static int [][] direction = new int[][]{{-1,1,-2,2,-2,2,-1,1},{-2,-2,-1,-1,1,1,2,2}};//马行走的八个方向。 public static void main(String[] args) { Scanner in = new Scanner(System.in); int count, row, col,cas = 0; int [][] map; Stack<Pos> stack = new Stack<Pos>(); count = in.nextInt(); while(count-->0){ stack.clear(); //清空栈。 row = in.nextInt();//读入地图行数。 col = in.nextInt();//读入地图列数。 map = new int[row][col]; map[0][0] = 1; //初始位置为 (0,0). stack.add(new Poj2488_20120802_3().new Pos(0,0));//初始位置入栈。 System.out.println("Scenario #" + (++cas)+ ":"); if(find(map,0,0,stack)){ // 如果查到符合条件的结果。 show(stack); //输出结果。 }else{ //否则输出 impossible System.out.println("impossible"); } System.out.println(); } } /** * 输入栈中的数据。 * @param stack */ private static void show(Stack<Pos> stack){ Stack<Pos> p = new Stack<Pos>(); while(!stack.isEmpty()){ p.add(stack.pop()); } while(!p.isEmpty()){ System.out.print(p.pop()); } System.out.println(); } /** * 搜索函数。 * @param map * @param x * @param y * @param stack * @return 如果搜索成功 ,返回 true. 否则返回 false. */ private static boolean find(int [][] map, int x, int y, Stack<Pos> stack){ int px,py,i, row, col, max; // 定义用到的变量。 row = map.length; //地图的行数。 col = map[0].length; // 地图的列数。 max = row*col; //栈中的最大元素数。 if(stack.size() == max){ // 如果栈中元素数达到最大值。返回 true. return true; }else{ for(i = 0; i < 8; ++i){ px = x + direction[0][i]; py = y + direction[1][i]; if(px >= 0 && px < map.length && py >= 0 && py < map[0].length && map[px][py]==0){ stack.add(new Poj2488_20120802_3().new Pos(px,py));//生成当前位置放入栈。 map[px][py] = 1; //标记当前点已在当前路径中。 if(find(map,px,py, stack)){ //递归搜索下一个位置。如果下一位置 搜索成功。 则返回 true return true; }else{ map[px][py] = 0; //回溯。 stack.pop();//弹出路径信息。 } } } } return false; //搜索结束返回 false; } /** * 路径中的位置信息。 * @author Administrator * */ private class Pos{ private int x; private int y; public Pos(){ } public Pos(int x, int y){ this.x = x; this.y = y; } public void setX(int x){ this.x = x; } public void setY(int y){ this.y = y; } public void set(int x, int y){ this.x = x; this.y = y; } public int getX(){ return x; } public int getY(){ return y; } public String toString(){ //按题要求重写的toString() 方法。 StringBuffer sb = new StringBuffer(); sb.append((char)(y+'A')); sb.append(x+1); return sb.toString(); } } }