HDU 2553 N皇后问题

来源:互联网 发布:淘宝号出售批发 编辑:程序博客网 时间:2024/06/16 01:01

                                        N皇后问题

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

 

Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
 

Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
 

Sample Input
1850
 

Sample Output
19210思路:我们没必要针对每个点的行和列进行判断,弄一个数组,即可判断行和列了,对斜线的判断也很简单,
 附上详细解释:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
#define maxn 20
int n;
int a[maxn],f[maxn],sum;
bool check(int t)
{
    for(int i=1;i<t;i++)//此循环用来判断列或斜线
    {
        if(f[i]==f[t]//判断是否在同一列|| t-i==abs(f[i]-f[t])//判断是否在同一斜线)//因为前面那个for循环我们已经判断了行,现在只用判断列和斜线方向就好了
        {
            return 0;
        }
    }
    return 1;
}
void dfs(int t)
{
    if(t>n)
    {
        sum++;//如果完成一次遍历,就加一,记录不同的种数
    }else{
        for(int i=1;i<=n;i++)
        {
            f[t]=i;//第二次搜索时,让其从1开始,因为前一次搜索,我们已经对其进行赋值,所以for循环的前t-1次循环都是用来让第t个皇后的行向下移动;
            if(check(t))//对第t列进行查找
            {
                dfs(t+1);
            }
        }
    }
}
int main()
{
     int i;
     memset(a,0,sizeof(a));//其实这两行用不用都无所谓
     memset(f,0,sizeof(f));//
     for(i=1;i<=10;i++)
     {
         sum=0,n=i;
         dfs(1);//每一次从1开始,搜到i,看看有多少种
         a[i]=sum;//把找到的值全部赋给a[i]
     }
     while(cin>>n)
     {
         if(n==0) break;
         cout<<a[n]<<endl;
     }
     return 0;      
}
0 0