N皇后问题 HDU - 2553(回溯/DFS/打表)

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1
8
5
0
Sample Output
1
92
10

我的题解:n皇后问题应该算是最经典的回溯算法的例子.不过我在写的DFS递归超时了,气的我打了个表交上去.hhhh

用非递归的方法写可能就不会超了,但我太懒了,打表大法好

我本来使用二维数组,参考了网上的blog,改成了一维数组,太强了,我怎么就想不到???!!!!!!!

大概就3个步骤,逐行逐行的试,可以保证每行只有一个皇后;检查同一列是否有皇后;检查对角线是否有皇后.

DFS

#include <bits/stdc++.h>
const int N=20;
using namespace std;
//int mp[N][N];
int mp[N];//使用一维数组
int ans;
int n;
/*
void op(){
    for(int i=1;i<=n;i++) printf("%d ",mp[i]); puts("");
}*/
bool ck(int x,int y){
    for(int i=1;i<=x-1;i++) if(x-i==abs(mp[i]-y)) return false;
    return true;
}
bool isempty(int m){
    for(int i=1;i<=n;i++) if(mp[i]==m) return false;
    return true;
}
void dfs(int now,int end){
    for(int i=1;i<=end;i++){
        if(ck(now,i)&&isempty(i)){
            if(now==end) ans++;
            else mp[now]=i,dfs(now+1,end),mp[now]=0;
        }
    }
}
int Nqueue(int n){
    memset(mp,0,sizeof(mp));
    ans=0;
    dfs(1,n);
    return ans;
}
int main()
{
    while(cin>>n&&n!=0){
        cout<<Nqueue(n)<<endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
}

打表


#include <iostream>

using namespace std;
int a[11]={0,1,0,0,2,10,4,40,92,352,724};
int main()
{
    int n;
    while(cin>>n&&n!=0){
        cout<<a[n]<<endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
}
posted @ 2019-04-03 01:11  _yjun  阅读(358)  评论(0编辑  收藏  举报