八皇后问题 (全排列的运用)

8皇后问题相信大家都听说过:

在一个8*8格子的矩形里,放上8个皇后,如果在同一直线上(横,竖,(左右)斜线)存在两个皇后,他们就互相攻击了,现在要我们来求一共有多少种摆法,让他们相安无事!

一般的解法都是回溯法,一步一步的试探,不行就返回再来,这样做时间效率很低,2的64次方,

今天我介绍的是全排列法解此题:

我们可以把这个问题抽象出来:

1.序号为0-7的8个皇后;

2.放置到序号为0-7的8个箱子里;

3.同时所有皇后的序号与箱子序号的和各不相同;

4.所有皇后的序号与箱子序号的差也各不相同。

前两条相当于横方向和竖方向都是唯一的,(用全排列实现)(用递归实现的全排列)

后两天相当于(左右)斜线上也都唯一的,(直接过滤)

嗯,写到这里大家应该明白所以然了吧。

代码如下

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Demo1 {
    public static List<List<Integer>>list = new ArrayList<List<Integer>>();
    private static void sort(List<Integer> datas, List<Integer> target) {
        if (datas.size()==0) {
            Set<Integer> s1 = new HashSet<Integer>();
            Set<Integer> s2 = new HashSet<Integer>();
            for(int i=0;i<target.size();i++){
                s1.add(i+target.get(i));
                s2.add(i-target.get(i));
            }
            if(s1.size()==8&&s2.size()==8){
                list.add(target);
            }
            return;
        }
        for (int i = 0; i < datas.size(); i++) {
            List<Integer> newDatas = new ArrayList<Integer>(datas);
            List<Integer> newTarget = new ArrayList<Integer>(target);
            newTarget.add(newDatas.get(i));
            newDatas.remove(i);
            sort(newDatas, newTarget);
        }
    }  

    public static void main(String[] args) {
        List<Integer> li = new ArrayList<Integer>();
        for(int i=0;i<8;i++){
            li.add(i);
        }
        sort(li, new ArrayList<Integer>());
        System.out.println(list.size());
    }
}

结果大家都知道:92

我没计算时间,因为结果是立刻蹦出来的,我也用此方法计算了“10皇后”的问题,只需要4秒!

八皇后问题 (全排列的运用)

时间: 2024-11-08 19:01:20

八皇后问题 (全排列的运用)的相关文章

八皇后和全排列

经典的递归程序设计中的2到题目 1.八皇后问题 国际象棋棋盘走法,用递归实现所有的可能性: 棋盘: (1).代码如下: #include<stdio.h> typedef unsigned char boolean; #define TRUE        1 #define FALSE        0 #define EIGHT    8 void showChess(int (*chess)[EIGHT]);  //显示棋盘 boolean isSafe(int (*chess)[EIG

LeetCode 31:递归、回溯、八皇后、全排列一篇文章全讲清楚

本文始发于个人公众号:TechFlow,原创不易,求个关注 今天我们讲的是LeetCode的31题,这是一道非常经典的问题,经常会在面试当中遇到.在今天的文章当中除了关于题目的分析和解答之外,我们还会详细解读深度优先搜索和回溯算法,感兴趣的同学不容错过. 链接 Next Permutation 难度 Medium 描述 实现C++当中经典的库函数next permutation,即下一个排列.如果把数组当中的元素看成字典序的话,那下一个排列即是字典序比当前增加1的排列.如果已经是字典序最大的情况

《编程之法》1.3字符串的全排列,组合,重复排列,八皇后问题

题目描述:输入一个字符串,打印出该字符串中字符的所有排列,例如输入"abc",输出"abc","acb","bac","bca","cab","cba" 解法一:递归实现 类似于图的深度遍历搜索求全路径的算法,每次交换两个数,并输出,按照递归的方法,如求abcd的全排序,1:先求abcd后面的bcd全排列(同样先求b后面cd的全排列,然后b与后面的元素依次交换);2:

【剑指offer】八皇后问题

转载请注明出处:http://blog.csdn.net/ns_code/article/details/26614999 剑指offer上解决八皇后问题,没实用传统的递归或非递归回溯法,而是用了非常巧妙的全排列法. 先说下八皇后问题:在8 X 8的国际象棋上摆放八个皇后,使其不能相互攻击,即随意两个皇后不得处于同一行,同一列或者允许对角线上,求出全部符合条件的摆法. 全排列解决八皇后问题的思路例如以下: 因为8个皇后不能处在同一行,那么肯定每一个皇后占领一行,这样能够定义一个数组A[8],数组

八皇后问题解析

今天下午思考了几个小时,最后还是选择走.net,虽然java现在很火,但毕竟学了一学期c#了,本人还是比较细化wp的,所以最后选择了.net.我相信只要学精,不管以后就业如何,都应该差不到哪去. 不扯远了,现在就来说一说八皇后问题.现在我还是大三学生,前几周上java实验课的时候我们实现了全排列问题,还剩一节课,老师就讲了下八皇后问题(就是在8x8的棋盘上,八个皇后两两不能在一条直线上),当时上课没认真听,下课去看有点看不懂,后来去看了其他博主的博文,更是看不懂,最后还是看老师写的代码.细细审看

54. 八皇后问题[eight queens puzzle]

[本文链接] http://www.cnblogs.com/hellogiser/p/eight-queens-puzzle.html [题目] 在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行.同一列或者同一对角斜线上.下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法.请求出总共有多少种摆法. [分析] 之前博文28.字符串的排列[StringPermutation]介绍过字符串的全排列,八皇后问题也可以转换为全排列问题. 由于八个皇后的任意两个不

字符串排列与八皇后问题

字符串排列问题 输入一个字符串,输出该字符串的所有排列.如输入abc,则输出abc,acb,bca,caab,cba.根据排列组合的知识,3个字符串的排列有3!=6个. 先考虑字符没有重复的情况: 可以将字符分成两个部分,第一部分为第一个字符,第二部分为后面的部分. 这样abc的排列情况可以这么分析: a+bc; b+ac; c+ab; 即将第一个字符一次与后面的每一个字符交换,然后分别求剩余部分的排列.这种思想将原来为n的问题变成了n-1的问题.用递归实现: 下面是<剑指offer上的代码>

递归 八皇后

递归 八皇后 题意 > 棋子不能在同一行,同一列,以及同一对角线. > 输出所有符合要求的情况. 步骤:用计数器统计次数,按列写出全排列,再枚举任意两个棋子,如果不符合条件,则计数器不变. #include <cstdio> #include <algorithm> const int maxn = 100; int n, p[maxn], hashTable[maxn] = {false}; int count = 0; void generateP(int inde

回溯 八皇后

回溯 八皇后 题意 > 棋子不能在同一行,同一列,以及同一对角线. > 输出所有符合要求的情况. 步骤:用计数器统计次数,按列写出全排列,再枚举任意两个棋子,如果不符合条件,则计数器不变.与直接递归不同的是,用到了剪枝技巧,如果不符合要求,则立即开始下一个状况 #include <cstdio> #include <algorithm> const int maxn = 100; int n, p[maxn], hashTable[maxn] = {false}; in