【N皇后】

简介: 【N皇后】

n-皇后问题

n−皇后问题是指将 n 个皇后放在 n×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

输入格式

共一行,包含整数 n 。

输出格式

每个解决方案占 n 行,每行输出一个长度为 n 的字符串,用来表示完整的棋盘状态。

其中 . 表示某一个位置的方格状态为空,Q 表示某一个位置的方格上摆着皇后。

每个方案输出完成后,输出一个空行。

注意:行末不能有多余空格。

输出方案的顺序任意,只要不重复且没有遗漏即可。

数据范围

1≤n≤9

输入样例:

4

输出样例:

.Q..
...Q
Q...
..Q.
..Q.
Q...
...Q
.Q..

题解

这里我们运用 深度优先遍历(dfs)的方法解题

方法一

全排列法
将所有的路径一一排列出来
在排列的时候进行条件判断
不符合的排列直接回溯

从第一行的第一个位置开始进行枚举到第一行的最后一个位置

进行排列组合

在进行排列组合的过程中对不符合的进行 剪枝

条件:两个皇后都不能处于同一行、同一列或同一斜线上。

如图,这是所有排列中的两种方法,

绿色的排列不符合要求,
红色的排列组合符合要求

定义一个路径数组用来储存所走路径上的值。

同时定义col列,dg对角线,udg反对角线数组,判断是否符合放置皇后的条件

#include <iostream>
using namespace std;
const int N = 20; 
// bool数组用来判断搜索的下一个位置是否可行
// col列,dg对角线,udg反对角线
// g[N][N]用来存路径
int n;
char g[N][N];
bool col[N], dg[N], udg[N];
void dfs(int u) {
    // u == n 表示已经搜了n行,故输出这条路径
    if (u == n) {
        for (int i = 0; i < n; i ++ ) puts(g[i]);  
        puts("");  
        return;
    }
    for (int i = 0; i < n; i ++ )
        // 剪枝(对于不满足要求的点,不再继续往下搜索)  
        // udg[n - u + i],+n是为了保证下标非负
        if (!col[i] && !dg[u + i] && !udg[n - u + i]) {
            g[u][i] = 'Q';
            col[i] = dg[u + i] = udg[n - u + i] = true;
            dfs(u + 1);
            // 恢复现场
            col[i] = dg[u + i] = udg[n - u + i] = false;
            g[u][i] = '.';
        }
}
int main() {
    cin >> n;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            g[i][j] = '.';
    dfs(0);
    return 0;
}   

方法二

这个方法比较原始。

从头开始一个一个位置的判断是否放置皇后,并用s记录皇后的数量,当到最后一个位置且放置皇后的数量s==n时,说明该条路径符合要求,并输出。

#include<iostream>
const int N=20;
int n;
bool col[N] , row[N], dg[N] , udg[N]; 
char path[N][N];
using namespace std;
void dfs(int x, int y, int s)
{
    if (y == n)
    {
        y = 0; x++;
    }
    if (x == n)
    {
        if (s == n)
        {
            for (int i = 0; i < n; i++)
            {
                cout << path[i] << endl;
            }
            cout << endl;
        }
        return;
    }
//放皇后
if (!row[x] && !col[y] && !dg[n + y - x] && !udg[y + x])
{
    path[x][y] = 'Q';
    row[x] = col[y] = dg[n + y - x] =udg[y + x] = true;
    dfs(x, y + 1, s + 1);
    path[x][y] = '.';
    row[x] = col[y] = dg[n + y - x] = udg[y + x] = false;
}
//不放皇后
dfs(x, y + 1, s);
}
int main()
{
  cin>>n;
  for(int i=0;i<n;i++)
  {
      for(int j=0;j<n;j++)
      {
          path[i][j]='.';
      }
  }
  dfs(0,0,0);
  return 0;
}

只是在上一个的解法上进行调整,但该解法的时间复杂度远大于第一种解法,当n足够大时,第二种解法会超时。

相关文章
|
4月前
|
机器学习/深度学习
leetcode-52:N皇后 II
leetcode-52:N皇后 II
15 0
|
8月前
|
算法
数星星(树状数组模板题)
数星星(树状数组模板题)
28 0
|
11月前
|
机器学习/深度学习 算法 安全
LeetCode - #52 N皇后 II
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
LeetCode - #52 N皇后 II
|
人工智能 算法 搜索推荐
LeetCode 周赛 338,贪心 / 埃氏筛 / 欧氏线性筛 / 前缀和 / 二分查找 / 拓扑排序
大家好,我是小彭。 上周末是 LeetCode 第 338 场周赛,你参加了吗?这场周赛覆盖的知识点很多,第四题称得上是近期几场周赛的天花板。
80 0
|
机器学习/深度学习 算法 Java
|
机器学习/深度学习 算法
【回溯算法篇】N皇后问题
【回溯算法篇】N皇后问题
【回溯算法篇】N皇后问题
|
算法 Go Python
LeetCode46:全排列(八皇后)
LeetCode46:全排列(八皇后)
LeetCode46:全排列(八皇后)