八皇后问题-递归算法 & 8重循环算法

八皇后问题-递归算法 & 8重循环算法

问题描述:在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一列或同一斜线上,问有多少种摆法。


import org.junit.Test;


/**
 * @Author chenc
 * @Date 2021/1/6 8:48
 * @Version 1.0
 * @Desc
 */
public class TestQ {
    
    

    int queenNum = 8;
    /**
     * 默认每行只放一个皇后,建立一个长度为8的数组,坐标对应的值即为该皇后坐在的列数,
     * 当数组没有重复值,即为摆放成功
     */
    int[] queenLocation = {
    
    -1, -1, -1, -1, -1, -1, -1, -1};

    int count = 0;

    @Test
    public void test_q() {
    
    

        System.out.println("暴力算法,8重循环");
        long b1_t = System.currentTimeMillis();
        brutal_func();
        System.out.println("用时: "+(System.currentTimeMillis() - b1_t));

        System.out.println("递归算法");
        long b2_t = System.currentTimeMillis();
        recursion_func();
        System.out.println("count: "+count);
        System.out.println("用时: "+(System.currentTimeMillis() - b2_t));

    }

    private void recursion_func() {
    
    
        int queenIndex = 0;
        findLocation(queenIndex);
    }

    /**
     * 给皇后找位置:
     * @param queenIndex 皇后的索引(0~7)
     */
    private void findLocation(int queenIndex) {
    
    

        if (queenIndex == queenNum){
    
     //所有的皇后走已经找到位置,即成功
            count++;
            printResult();
            return;
        }

        for (int i = 0; i < queenNum; i++) {
    
    //queenNum这里所表示的是皇后可以选择的位置数,恰好与皇后数相等
            if (isAvailableLocation(queenIndex, i)) {
    
    
                queenLocation[queenIndex] = i;
                findLocation(queenIndex + 1);
            }
        }
        //无法为queenIndex的皇后找到位置,那就需要调整上一皇后的位置,此时清楚上一皇后位置信息,避免干扰
        if (queenIndex != 0) {
    
    
            queenLocation[queenIndex-1] = -1;
            return;
        }

    }

    private void printResult() {
    
    
        for (int i = 0; i < queenLocation.length; i++){
    
    
            System.out.print(queenLocation[i]+" ");
        }
        System.out.println("");
    }

    private void brutal_func() {
    
    
        int succTime = 0;
        for (int l0 = 0; l0 < queenNum; l0++) {
    
    
            queenLocation[0] = l0;
            for (int l1 = 0; l1 < queenNum; l1++) {
    
    


                if (!isAvailableLocation(1, l1)) {
    
    
                    queenLocation[1] = -1;
                    continue;
                }
                queenLocation[1] = l1;
                for (int l2 = 0; l2 < queenNum; l2++) {
    
    

                    if (!isAvailableLocation(2, l2)) {
    
    
                        continue;
                    }
                    queenLocation[2] = l2;
                    for (int l3 = 0; l3 < queenNum; l3++) {
    
    

                        if (!isAvailableLocation(3, l3)) {
    
    
                            continue;
                        }
                        queenLocation[3] = l3;
                        for (int l4 = 0; l4 < queenNum; l4++) {
    
    

                            if (!isAvailableLocation(4, l4)) {
    
    
                                continue;
                            }
                            queenLocation[4] = l4;
                            for (int l5 = 0; l5 < queenNum; l5++) {
    
    

                                if (!isAvailableLocation(5, l5)) {
    
    
                                    continue;
                                }
                                queenLocation[5] = l5;
                                for (int l6 = 0; l6 < queenNum; l6++) {
    
    

                                    if (!isAvailableLocation(6, l6)) {
    
    
                                        continue;
                                    }
                                    queenLocation[6] = l6;
                                    for (int l7 = 0; l7 < queenNum; l7++) {
    
    

                                        if (!isAvailableLocation(7, l7)) {
    
    
                                            continue;
                                        }
                                        queenLocation[7] = l7;

                                        succTime++;
                                        System.out.println(l0 + " " + l1 + " " + l2 + " " + l3 + " " + l4 + " " + l5 + " " + l6 + " " + l7);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        System.out.println("总计有" + succTime + "种摆法!");
    }

    /**
     * 如果处在同一行、同一列、统一对角线判为false;默认在加入新元素之前,队列符合要求
     */
    private boolean isAvailableLocation(int i, int iV) {
    
    
        for (int index = 0; index < i; index++) {
    
    
            if ((queenLocation[index] == iV) ||
                    ((i - index) == (iV - queenLocation[index])) ||
                    ((i - index) == (queenLocation[index] - iV))
            ) {
    
    
                return false;
            }
        }
        return true;
    }


}

------------------------------结果-----------------------------

暴力算法,8重循环
0 4 7 5 2 6 1 3
0 5 7 2 6 3 1 4
0 6 3 5 7 1 4 2
0 6 4 7 1 3 5 2
1 3 5 7 2 0 6 4
1 4 6 0 2 7 5 3
1 4 6 3 0 7 5 2
1 5 0 6 3 7 2 4
1 5 7 2 0 3 6 4
1 6 2 5 7 4 0 3
1 6 4 7 0 3 5 2
1 7 5 0 2 4 6 3
2 0 6 4 7 1 3 5
2 4 1 7 0 6 3 5
2 4 1 7 5 3 6 0
2 4 6 0 3 1 7 5
2 4 7 3 0 6 1 5
2 5 1 4 7 0 6 3
2 5 1 6 0 3 7 4
2 5 1 6 4 0 7 3
2 5 3 0 7 4 6 1
2 5 3 1 7 4 6 0
2 5 7 0 3 6 4 1
2 5 7 0 4 6 1 3
2 5 7 1 3 0 6 4
2 6 1 7 4 0 3 5
2 6 1 7 5 3 0 4
2 7 3 6 0 5 1 4
3 0 4 7 1 6 2 5
3 0 4 7 5 2 6 1
3 1 4 7 5 0 2 6
3 1 6 2 5 7 0 4
3 1 6 2 5 7 4 0
3 1 6 4 0 7 5 2
3 1 7 4 6 0 2 5
3 1 7 5 0 2 4 6
3 5 0 4 1 7 2 6
3 5 7 1 6 0 2 4
3 5 7 2 0 6 4 1
3 6 0 7 4 1 5 2
3 6 2 7 1 4 0 5
3 6 4 1 5 0 2 7
3 6 4 2 0 5 7 1
3 7 0 2 5 1 6 4
3 7 0 4 6 1 5 2
3 7 4 2 0 6 1 5
4 0 3 5 7 1 6 2
4 0 7 3 1 6 2 5
4 0 7 5 2 6 1 3
4 1 3 5 7 2 0 6
4 1 3 6 2 7 5 0
4 1 5 0 6 3 7 2
4 1 7 0 3 6 2 5
4 2 0 5 7 1 3 6
4 2 0 6 1 7 5 3
4 2 7 3 6 0 5 1
4 6 0 2 7 5 3 1
4 6 0 3 1 7 5 2
4 6 1 3 7 0 2 5
4 6 1 5 2 0 3 7
4 6 1 5 2 0 7 3
4 6 3 0 2 7 5 1
4 7 3 0 2 5 1 6
4 7 3 0 6 1 5 2
5 0 4 1 7 2 6 3
5 1 6 0 2 4 7 3
5 1 6 0 3 7 4 2
5 2 0 6 4 7 1 3
5 2 0 7 3 1 6 4
5 2 0 7 4 1 3 6
5 2 4 6 0 3 1 7
5 2 4 7 0 3 1 6
5 2 6 1 3 7 0 4
5 2 6 1 7 4 0 3
5 2 6 3 0 7 1 4
5 3 0 4 7 1 6 2
5 3 1 7 4 6 0 2
5 3 6 0 2 4 1 7
5 3 6 0 7 1 4 2
5 7 1 3 0 6 4 2
6 0 2 7 5 3 1 4
6 1 3 0 7 4 2 5
6 1 5 2 0 3 7 4
6 2 0 5 7 4 1 3
6 2 7 1 4 0 5 3
6 3 1 4 7 0 2 5
6 3 1 7 5 0 2 4
6 4 2 0 5 7 1 3
7 1 3 0 6 4 2 5
7 1 4 2 0 6 3 5
7 2 0 5 1 4 6 3
7 3 0 2 5 1 6 4
总计有92种摆法!
用时: 8
递归算法
0 4 7 5 2 6 1 3
0 5 7 2 6 3 1 4
0 6 3 5 7 1 4 2
0 6 4 7 1 3 5 2
1 3 5 7 2 0 6 4
1 4 6 0 2 7 5 3
1 4 6 3 0 7 5 2
1 5 0 6 3 7 2 4
1 5 7 2 0 3 6 4
1 6 2 5 7 4 0 3
1 6 4 7 0 3 5 2
1 7 5 0 2 4 6 3
2 0 6 4 7 1 3 5
2 4 1 7 0 6 3 5
2 4 1 7 5 3 6 0
2 4 6 0 3 1 7 5
2 4 7 3 0 6 1 5
2 5 1 4 7 0 6 3
2 5 1 6 0 3 7 4
2 5 1 6 4 0 7 3
2 5 3 0 7 4 6 1
2 5 3 1 7 4 6 0
2 5 7 0 3 6 4 1
2 5 7 0 4 6 1 3
2 5 7 1 3 0 6 4
2 6 1 7 4 0 3 5
2 6 1 7 5 3 0 4
2 7 3 6 0 5 1 4
3 0 4 7 1 6 2 5
3 0 4 7 5 2 6 1
3 1 4 7 5 0 2 6
3 1 6 2 5 7 0 4
3 1 6 2 5 7 4 0
3 1 6 4 0 7 5 2
3 1 7 4 6 0 2 5
3 1 7 5 0 2 4 6
3 5 0 4 1 7 2 6
3 5 7 1 6 0 2 4
3 5 7 2 0 6 4 1
3 6 0 7 4 1 5 2
3 6 2 7 1 4 0 5
3 6 4 1 5 0 2 7
3 6 4 2 0 5 7 1
3 7 0 2 5 1 6 4
3 7 0 4 6 1 5 2
3 7 4 2 0 6 1 5
4 0 3 5 7 1 6 2
4 0 7 3 1 6 2 5
4 0 7 5 2 6 1 3
4 1 3 5 7 2 0 6
4 1 3 6 2 7 5 0
4 1 5 0 6 3 7 2
4 1 7 0 3 6 2 5
4 2 0 5 7 1 3 6
4 2 0 6 1 7 5 3
4 2 7 3 6 0 5 1
4 6 0 2 7 5 3 1
4 6 0 3 1 7 5 2
4 6 1 3 7 0 2 5
4 6 1 5 2 0 3 7
4 6 1 5 2 0 7 3
4 6 3 0 2 7 5 1
4 7 3 0 2 5 1 6
4 7 3 0 6 1 5 2
5 0 4 1 7 2 6 3
5 1 6 0 2 4 7 3
5 1 6 0 3 7 4 2
5 2 0 6 4 7 1 3
5 2 0 7 3 1 6 4
5 2 0 7 4 1 3 6
5 2 4 6 0 3 1 7
5 2 4 7 0 3 1 6
5 2 6 1 3 7 0 4
5 2 6 1 7 4 0 3
5 2 6 3 0 7 1 4
5 3 0 4 7 1 6 2
5 3 1 7 4 6 0 2
5 3 6 0 2 4 1 7
5 3 6 0 7 1 4 2
5 7 1 3 0 6 4 2
6 0 2 7 5 3 1 4
6 1 3 0 7 4 2 5
6 1 5 2 0 3 7 4
6 2 0 5 7 4 1 3
6 2 7 1 4 0 5 3
6 3 1 4 7 0 2 5
6 3 1 7 5 0 2 4
6 4 2 0 5 7 1 3
7 1 3 0 6 4 2 5
7 1 4 2 0 6 3 5
7 2 0 5 1 4 6 3
7 3 0 2 5 1 6 4
count: 92
用时: 16

-----暴力算法,实则有更好的时间效率。

Guess you like

Origin blog.csdn.net/cc890824/article/details/106497716