POJ 2488 A Knight's Journey

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.

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.

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();
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值