N皇后問題||HDU2553

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2553
Problem Description

在N*N的方格棋盤放置了N個皇后,使得它們不相互攻擊(即任意2個皇后不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。
你的任務是,對於給定的N,求出有多少種合法的放置方法。

Input

共有若干行,每行一個正整數N≤10,表示棋盤和皇后的數量;如果N=0,表示結束。

Output

共有若干行,每行一個正整數,表示對應輸入行的皇后的不同放置數量。

Sample Input

1
8
5
0

Sample Output

1
92
10

題解:這道題一開始並沒有思路,是看了一個大佬的然後理解了自己敲出來的
思路的話,首先要搞清楚如果一行或者一列或者同在45°的一條線放了一個棋子,那麼剩下的位置就不能再放置了。
如果我們按行遍歷,那麼這三個方向都有共同點,一個是列數相等,一個是列數-行數的值相等,一個是列數+行數值相等。
這樣的話我們可以開始一個深度遍歷,先設置一個標記變量使它能夠表示這個位置是否可以放置棋子,然後一行一行的開始,然後一列挨着一列遍歷,遇到一個符合條件的就進入下一行,最後如果遍歷的行數和N相等,那麼就代表有一種方法,然後退出這層遍歷,並把剛剛標記值初始化(因爲我們已經知道這個點可以放置,但是我們遍歷下一點的時候他可能已經被標記過,然而我們目前這個方案並沒有在那個點放置,所以需要初始化)。
具體看代碼。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int vis[3][50],a[50];
int n,sum;
void dfs(int row)
{
    int i;
    if(row==n+1)//已經遍歷了N行 
    {
        sum++;
        return;
    }
    for(i=1;i<=n;i++)
    {
        if(vis[0][row-i+n]==0&&vis[1][i]==0&&vis[2][row+i]==0)//表示目前這三個方向沒有放置棋子 
        {
            vis[0][row-i+n]=vis[1][i]=vis[2][row+i]=1;//標記,假設已經放置 
            dfs(row+1);//遍歷下一行 
            vis[0][row-i+n]=vis[1][i]=vis[2][row+i]=0;//返回當前行,並把標記取消 
        }
    }
}
int main()
{
    for(n=1;n<=10;n++)//先打表,不然會超時 
    {
        sum=0;
        memset(vis,0,sizeof(vis));
        dfs(1);
        a[n]=sum;
    }
    int x;
    while(scanf("%d",&x),x)
    {
        printf("%d\n",a[x]);
    }
return 0;
} 
發佈了105 篇原創文章 · 獲贊 26 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章