Codeup100000609 问题 D: 【递归入门】n皇后 问题(原始的8皇后问题)回溯法优化

1

问题 D: 【递归入门】n皇后 问题(原始的8皇后问题)
时间限制: 1 Sec 内存限制: 128 MB
提交: 926 解决: 436
[提交][状态][讨论版][命题人:外部导入]
题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。

输入
一个整数n( 1 < = n < = 10 )

输出
每行输出对应一种方案,按字典序输出所有方案。每种方案顺序输出皇后所在的列号,相邻两数之间用空格隔开。如果一组可行方案都没有,输出“no solute!”
图1 五皇后
图一
如上图以a对应的排列为2、4、1、3、5;b对应的排列为3、5、1、4、2

样例输入
4
样例输出
2 4 1 3
3 1 4 2

2 解析

  • 题目:给定范围1~N内的全排序中,求出每一个排列中每个元素与该排列中其他的元素不在横、竖、斜线上的排列方案
  • 思路一:枚举1~N的全排列,每列举完一组,然后就在该组排列中测试当前方案是否合法(排列中每个元素与该排列中其他的元素不在横、竖、斜线上)
  • 思路二:在上一种的方案的前提下,进行回溯法优化,在每次全排列列举每一组元素时候,每列举一个元素,就判断一次是否和之前的元素冲突(排列中每个元素与该排列中其他的元素在横、竖、斜线上),如果不冲突就将元素放进该组中;如果冲突,就直接列举下一组

3 参考代码

  • 思路一:
#include <cstdio>
#include <cstdlib>

const int MAXN = 100;
int N;
bool hashTable[MAXN]  = {false};
int P[MAXN];
int count = 0;

void DFS(int index){//朴素算法
    if(index == N + 1){
        bool flag = true;//flag为true,表示当前方案合法
        for (int i = 1; i <= N ; ++i)//遍历两个皇后,
        {
            for (int j = i + 1; j <= N; ++j)
            {
                //第四象限内,P[y]为纵坐标,i、j为横坐标
                if(abs(i - j) == abs(P[j] - P[i])){//如果在一条对角线上,也就是正方形相对的两个端点
                    flag = false;
                }
            }
        }

        if(flag == true) {
            count++;
            for (int i = 1; i <= N; ++i)
            {
                printf("%d", P[i]);
                if(i <= N - 1) printf(" ");
            }
            printf("\n");
        }
    }

    for (int i = 1; i <= N; ++i)//全排列
    {
        if(hashTable[i] == false){
            P[index] = i;
            hashTable[i] = true;
            DFS(index + 1);
            hashTable[i] = false;
        }
    }
}

int main(){
    scanf("%d", &N);
    DFS(1);
    if(count == 0) printf("no solute!\n");
    return 0;
}
  • 思路二:
#include <cstdio>
#include <cstdlib>

const int MAXN = 100;
int N;
bool hashTable[MAXN]  = {false};
int P[MAXN];
int count = 0;

void DFS(int index){//朴素算法
    if(index == N + 1){
        count++;
            for (int i = 1; i <= N; ++i)
            {
                printf("%d", P[i]);
                if(i <= N - 1) printf(" ");
            }
            printf("\n");
            return;
        }


    for (int i = 1; i <= N; ++i)//第i行
    {
        if(hashTable[i] ==  false){
            bool flag = true;
            for (int pre = 1; pre < index; ++pre)
            {
                //第index列的皇后行号为i,第pre列的行号为P[pre]
                if(abs(index - pre) == abs(P[pre] - i)){
                    flag = false;
                    break;
                }
            }

            if(flag == true){
                P[index] = i;
                hashTable[i] = true;
                DFS(index + 1);
                hashTable[i] = false;
            }
        }
        
    }
}

int main(){
    scanf("%d", &N);
    DFS(1);
    if(count == 0) printf("no solute!\n");
    return 0;
}
发布了321 篇原创文章 · 获赞 51 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_33375598/article/details/104059358