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

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秒!

 

posted on 2014-08-07 16:12  asonga  阅读(840)  评论(1编辑  收藏  举报

导航