解八皇后java实现

package com.yss.java;


public class Test01 {
	
	/**
	 * @author WangHang
	 * 抽象成数学条件为:不能同行,不能同列,不能同对角线
	 * 那么可以得出结论,符合条件的结果,每一行,每一列上有且仅有一个元素
	 * 因此可以让第一个元素在第一行上移动,第二个元素在第二行上移动,依次类推
	 * 在放置了第n个元素在第n行后,放置第n+1个元素的时候只需要判断哪些列被占用,哪些斜线上不能放置
	 * 判断斜线上能否放置,只需要判断当前元素在行和列上距离已放置的元素格子是否相等
	 * 比如(2,3)上已放置元素,那么(4,5)和(4,1)在行和列上都距离(2,3)两格,所以不能放置
	 * 用一个一维数组来记录哪些列被占用,用另一个以为数组来记录已放置的元素在哪一列
	 */
	
	/*
	 * 用来记录哪一个列被占用,数组的第n个元素表示第n列,1表示未占用,0表示已占用
	 * 比如,数组的第5个元素即column[4]=0,表示第4列已占用
	 * 初始值全部为0,从第一行开始,占用一列,就把这一列的元素置0
	 */
	int column[] = new int[8];   
	
	/*
	 * 用来记录放置在这一行的那一列,数组的第n个元素表示第n行
	 * 数组的值,表示放置在这一行的那一列
	 * 比如,数组的第3个元素即res[2]的值为4,放置在第三行的第4列
	 */
	int res[] = new int[8];
	
	
	static int sum = 0;				//记录输出了多少次可能的组合
	
	
	/*
	 * main函数入口
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Test01 t = new Test01();
		t.init();    //初始化column数组
		new Test01().analysis(1, t.column); //传递的参数1,表示从第1列开始
		System.out.println(sum);
	}
	
	
	/*
	 * 初始化函数
	 */
	public void init(){
		for (int i = 0; i < 8 ; i++) {
			column[i] = 1;
		}
	}
	
	
	/*
	 * 运算函数
	 */
	public void analysis(int num, int[] column){
		//8行都满足的情况下调用输出
		if( num > 8 ){
			showAnswer();
		}else{
			for (int i = 1; i <= 8 ; i++) {
				if( num > 1 ){
					//判断列是否被占用
					if(column[i-1] == 0){
						continue;
					}
					boolean flag = false;
					for (int j = 0; j < num-1; j++) {
						//判断写线上是否能放置
						if((i-res[j])==(num-j-1)||(i-res[j])==(j+1-num)){
							//不能放置就退出循环
							flag = true;
							break;
						}
					}
					//斜线上不能放置,继续下次循环
					if(flag){
						continue;
					}
				}
				//记录不能放置的列
				column[i-1] = 0;
				//记录当前行放置在了那一列(num表示行,i是当前行的列)
				res[num-1] = i;
				//当前行放置好后,递归调用,进入下一行的判断
				analysis(num+1, column);
				/*
				 * 如果n+1行有满足的列,在退出循环后进入n行的下次循环前,要把n+1行已记录的列信息抹掉
				 * 如果res里面记录的列信息不为0,就取出来,然后抹掉column里面记录的占用信息
				 * 再把res里记录的列信息也抹掉,然后进入上一行的下次循环
				 */
				if(res[num-1]!=0)
					column[res[num-1]-1]=1;
				res[num-1]=0;
			}
		}
	}
	
	/*
	 * 输出函数
	 */
	public void showAnswer(){
		System.out.println();
		sum++;
		for (int i : res) {
			System.out.print(i+"\t");
		}
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值