DFS - 排列數字 + n-皇后問題

DFS - 排列數字 + n-皇后問題

1、排列數字

給定一個整數n,將數字1~n排成一排,將會有很多種排列方法。

現在,請你按照字典序將所有的排列方法輸出。

輸入格式
共一行,包含一個整數n。

輸出格式
按字典序輸出所有排列方案,每個方案佔一行。

數據範圍
1≤n≤7
輸入樣例:
3
輸出樣例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1


分析:

nu[1,n]使un依次枚舉n位數的每一位u,對每一位還要依次枚舉[1,n]的所有數字,\\若當前數字還未被使用過,就將該數字填入第u位上。\\若已經枚舉了n位,就將結果輸出,結束遞歸。

根據上述思路能夠畫出一顆遞歸樹。\\以樣例爲例,作出下圖:
在這裏插入圖片描述
遞歸的順尋是從左到右的。

使因爲每次都是直接遞歸到底,就是相當於枚舉完一個排列數,\\因此我們可以用一個數組來記錄本次枚舉的排列數的每一位放的什麼數字,再用一個數組標記當前已經使用了哪些數字。

具體落實:

pathst使①、用一個path數組記錄每次枚舉的方案,st數組來標記正在枚舉的排列數中有哪些數字已經被使用過了。

dfsuni使u②、dfs枚舉排列數的第u位放什麼數字,若已經放了n位,就輸出記錄的答案,結束遞歸。\\\qquad否則就依次枚舉放哪個數字,若當前數字i在本次遞歸還未使用過,就將其放在第u位,同時標記這個數字。\\\qquad注意,枚舉完一種排列數後,要依次將之前標記過的數字取消標記,這個過程是回溯的過程。

代碼:

#include<iostream>

using namespace std;

const int N=10;

int n,path[N];
bool st[N];

void dfs(int u)
{
    if(u==n) 
    {
        for(int i=0;i<n;i++) cout<<path[i]<<' ';
        cout<<endl;
        return ;
    }
    
    for(int i=1;i<=n;i++)
        if(!st[i])
        {
            path[u]=i;
            st[i]=true;
            dfs(u+1);
            st[i]=false;
        }
}

int main()
{
    cin>>n;
    
    dfs(0);
    
    return 0;
}

2、n-皇后問題

n-皇后問題是指將 n 個皇后放在 n∗n 的國際象棋棋盤上,使得皇后不能相互攻擊到,即任意兩個皇后都不能處於同一行、同一列或同一斜線上。

在這裏插入圖片描述

現在給定整數n,請你輸出所有的滿足條件的棋子擺法。

輸入格式
共一行,包含整數n。

輸出格式
每個解決方案佔n行,每行輸出一個長度爲n的字符串,用來表示完整的棋盤狀態。

其中”.”表示某一個位置的方格狀態爲空,”Q”表示某一個位置的方格上擺着皇后。

每個方案輸出完成後,輸出一個空行。

輸出方案的順序任意,只要不重複且沒有遺漏即可。

數據範圍
1≤n≤9

輸入樣例:
4

輸出樣例:
.Q..
...Q
Q...
..Q.

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

分析:

nn使每行只放一個皇后,每行能夠放的位置有限,\\n行可以視作一個n位數的排列,每一位枚舉當前行哪些列能夠擺放皇后,即有哪些數字還沒有被使用過。

轉化爲與第一題排列數字相似的問題。

3不同的是,這裏需要用3個數組來標記,列、正對角線、反對角線。
(u,i)u+inu+i它們之間的座標關係如下:\\對座標爲(u,i)的位置,其正對角線的下標爲u+i,反對角線的下標爲n-u+i。
在這裏插入圖片描述

代碼:

#include<iostream>
#include<cstring>

using namespace std;

const int N=10;

int n;
char g[N][N];
bool col[N],dg[N],udg[N];

void dfs(int u)
{
    if(u==n)
    {
        for(int i=0;i<n;i++) puts(g[i]);
        puts("");
        return ;
    }
    
    for(int i=0;i<n;i++)
        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);
            g[u][i]='.';
            col[i]=dg[u+i]=udg[n-u+i]=false;
        }
}

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章