java实现N皇后迭代算法

这里是java实现N皇后问题的迭代算法:


package NQueenesProblem;

import java.util.Scanner;

//这里是N皇后回溯算法
/**
 * 
 * @author YuYunTan(谭淇蔚)
 *回溯法:也称为试探法,它并不考虑问题规模的大小,
 *而是从问题的最明显的最小规模开始逐步求解出可能的答案,
 *并以此慢慢地扩大问题规模,迭代地逼近最终问题的解。
 *这种迭代类似于穷举并且是试探性的,因为当目前的可能答案被测试出不可能可以获得最终解时,
 *则撤销当前的这一步求解过程,回溯到上一步寻找其他求解路径。
 *为了能够撤销当前的求解过程,必须保存上一步以来的求解路径,这一点相当重要。
 *N 皇后问题:
 *在一个 N * N 的国际象棋棋盘中,
 *怎样放置 N 个皇后才能使 N 个皇后之间不会互相有威胁而共同存在于棋局中,
 *即在 N * N 个格子的棋盘中没有任何两个皇后是在同一行、同一列、同一斜线上。
 *求解思路:
 *最容易想到的方法就是有序地从第 1 列的第 1 行开始,
 *尝试放上一个皇后,然后再尝试第 2 列的第几行能够放上一个皇后,
 *如果第 2 列也放置成功,那么就继续放置第 3 列,如果此时第 3 列没有一行可以放置一个皇后,
 *说明目前为止的尝试是无效的(即不可能得到最终解),那么此时就应该回溯到上一步(即第 2 步),
 *将上一步(第 2 步)所放置的皇后的位置再重新取走放在另一个符合要求的地方…如此尝试性地遍历加上回溯,
 *就可以慢慢地逼近最终解了。
 */
public class NQUEENS {
	

	private int x[];
	private static int d=0;
	NQUEENS(int n){
		x = new int [n+1];//n皇后问题,x[0]不要
	}
	/**
	 * x[k]表示第k个皇后放在第k行第x[k]列
	 */
	public static void main(String[] args) {
		int s;
		Scanner input = new Scanner(System.in);
		s = input.nextInt();
		System.out.println("---------------------------------");
		System.out.println("华丽丽的"+s+"皇后问题解");
		NQUEENS a = new NQUEENS(s);
		a.Nqueens(s);
		System.out.println(s+"皇后一共有"+d+"个解!");
		input.close();
	}
	
	public void Nqueens(int n){
		x[1]=0;
		int k=1;//k表示当前行,x[k]是当前列
		while(k>0){
			x[k]=x[k]+1;//移到下一列
			while((x[k] <= n) && !place(k))
				x[k]=x[k]+1;//观测是否在其列,没出列,其次,观测是否能放在这个列,不能下一个列检测
			
			if(x[k] <= n){//找到一个位置
					if( k == n){//是否是一个完整的解
						d++;
						print(x);//是则打印					
					}
					else{
						k=k+1;//下一个皇后
						x[k]=0;
					}
				}else{
					k = k-1;//回溯搜索
				}			
		}
	}
	
	private void print(int[] x2) {
		// TODO 自动生成的方法存根
		System.out.println((x2.length-1)+"皇后的解为:");
		for(int i=1;i<x2.length;i++){
			System.out.print(" "+x2[i]);
		}
		System.out.println("");
	}
	
	//测试x[k]是否合理
	private boolean place(int k) {
		// TODO 自动生成的方法存根
		//如果一个皇后能放在第k行和x[k]列则返回true;
		//否则返回false。x是一个全程数组,进入此过程时已置了k个指,其中k不大于长度n
		int i = 1;
		while(i<k){
			
			if(x[i] == x[k] || Math.abs(x[i]-x[k]) == Math.abs(i-k)){
				//同一列有两个皇后以及在同一个对角线上
				return false;
			}
			i++;
		}
		return true;//满足条件
	}	
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YuYunTan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值