马踏棋盘的Java实现

package chow;


/**
 * 马踏棋盘问题,用贪婪法
 * 
 * @author chow
 * @date 2010-8-5
 */
public class HorseStep {
	static final int[] dx = { -1, -2, -2, -1, 1, 2, 2, 1 }; // x方向的增量
	static final int[] dy = { 2, 1, -1, -2, -2, -1, 1, 2 }; // y方向的增量
	static final int N = 8;
	static int[][] board = new int[N][N]; // 棋盘

	// 计算结点出口
	int waysOut(int x, int y) {
		int tx, ty;
		int count = 0;
		// 结点位置非法或已踏过,返回-1
		if (x < 0 || y < 0 || x >= N || y >= N || board[x][y] > 0) {
			return -1;
		}
		for (int i = 0; i < N; ++i) {
			tx = x + dx[i];
			ty = y + dy[i];
			if (tx < 0 || ty < 0 || tx >= N || ty >= N) {
				continue;
			}
			if (board[tx][ty] == 0) {
				count++;
			}
		}
		return count;
	}

	// 按结点出口数,从小到大排序
	void sortnode(HorseNode[] hn, int n)// 采用简单排序法,因为子结点数最多只有8
	{
		int i, j, t;
		HorseNode temp;
		for (i = 0; i < n; ++i) {
			for (t = i, j = i + 1; j < n; ++j)
				if (hn[j].waysOutNum < hn[t].waysOutNum)
					t = j;
			if (t > i) {
				temp = hn[i];
				hn[i] = hn[t];
				hn[t] = temp;
			}
		}
	}

	// 搜索函数,count代表当前第几步
	void dfs(int x, int y, int count) {
		int i, tx, ty;
		HorseNode[] tExit = new HorseNode[N]; // 记录出口结点的出口数

		if (count > N * N) {
			output();
			return;
		}
		// 计算[x,y]的出口结点和出口结点的出口数
		for (i = 0; i < N; i++) {
			tx = x + dx[i];
			ty = y + dy[i];
			HorseNode h = new HorseNode();
			tExit[i] = h;
			tExit[i].x = tx;
			tExit[i].y = ty;
			tExit[i].waysOutNum = waysOut(tx, ty);
		}
		
		sortnode(tExit, N);
		
		for(i = 0; tExit[i].waysOutNum < 0; ++i)
			;
		for(; i < N; ++i){
			tx = tExit[i].x;
			ty = tExit[i].y;
			board[tx][ty] = count;
			dfs(tx, ty, count + 1);
			board[tx][ty] = 0;
		}
	}
	
	public static void main(String[] args) {
		int x = 1;
		int y = 3;
		HorseStep test = new HorseStep();
		board[x][y] = 1;
		test.dfs(x, y, 2);
	}

	//打印结果
	void output(){
		for(int i = N - 1; i >= 0; --i){
			for(int j = 0; j < N; ++j){
				System.out.printf("%2d ", board[i][j]);
			}
			System.out.println();
		}
		System.exit(0);
	}
	
}

class HorseNode {
	int x;
	int y;
	int waysOutNum;
}
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值