算法笔记_072:N皇后问题(Java)

目录

1 问题描述

2 解决方案

 


1 问题描述

n个皇后放在一个n*n的棋盘上,使得任何两个皇后都不能相互攻击,即它们不能同行,不能同列,也不能位于同一条对角线上。

 


2 解决方案

本文采用全排列的方法,从n个皇后的全排列中寻找符合规则的皇后排列。

 

为什么这里是说 全排列呢?因为在N皇后问题中,棋盘每一行只准放一个皇后,且每一行的皇后必定要选一列。这个问题就相当于求取1~N个数字的全排列,假设全排列中一种排列方案中第一个数为x,则在棋盘第一行位置为第x列放一个皇后,其第i个位置的数y就为棋盘第i行的第y列放着一个皇后。

那么既然全排列能够得到,就要除去其中不符合条件的排列情况,此时只需要给相应排列加一个判断条件即可,符合条件的就输出这个排列,否则进入下一个排列判断。

 

具体代码如下:

package com.liuzhen.chapter12;

public class QueenProblem {
    public static int count = 0;
    //n皇后问题中皇后摆放位置满足的限制条件,若满足则返回true,否则返回false
    public boolean isOk(int[] result, int step) {
        for(int i = 0;i < step;i++) {
            for(int j = i + 1;j < step;j++) {
                int left = i - j;
                int right = j - i;
                if(result[j] == result[i] + left || result[j] == result[i] + right)
                    return false;
            }
        }
        return true;
    }
    //交换数组A中m位置和n位置上的值
    public void swap(int[] A, int m, int n) {
        int temp = A[m];
        A[m] = A[n];
        A[n] = temp;
    }
    
    public void printResult(int[] A, int step) {
        if(step == A.length) {  
            count++;
            for(int i = 0;i < A.length;i++)
                System.out.print(A[i]+" ");
            System.out.println();
            return;
        } else {
            for(int i = step;i < A.length;i++) {
                swap(A, i, step);   //执行回溯前的移位
                if(isOk(A, step + 1)) 
                    printResult(A, step + 1);
                swap(A, i, step);   //如果不满足条件或者已经完成一种方案,进行回溯处理
            }
        }    
    }
    
    public static void main(String[] args) {
        QueenProblem test = new QueenProblem();
        int[] A = {1,2,3,4};
        test.printResult(A, 0);
        System.out.println("符合n皇后排序条件的排序方式个数为:"+count);
    }
}

运行结果:

2 4 1 3 
3 1 4 2 
符合n皇后排序条件的排序方式个数为:2

 

 

参考资料:

1.n皇后问题

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值