N皇后问题 HDU - 2553

来源:互联网 发布:淘宝上一千多的三星s6 编辑:程序博客网 时间:2024/06/05 15:29
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。 
你的任务是,对于给定的N,求出有多少种合法的放置方法。 

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

Sample Output

19210
思路:明显是用回溯法,这里比较难的是对角线,列的状态表示,列的状态用vis[0][j]表示即可,对角线的表示比较麻烦,所以我用了刘汝佳的表示方法,vis[1][i+j]表示主对角线的状态,vis[2][j-i+n]来表示副对角线的状态(因为j-i有可能是负的,所以加n)

下面是ac代码(有可能因为测试数据过大,如果显示超时,直接打表)

#include<cstdio>
#include<string.h>
int vis[3][100],n,ans;
void dfs(int x)
{
    if(x>=n)
    {
        ans++;
        return;
    }
    for(int i=0;i<n;i++)
    {
            if(!vis[0][i]&&!vis[1][i+x]&&!vis[2][i-x+n])
            {
                vis[0][i]=vis[1][i+x]=vis[2][i-x+n]=1;
                dfs(x+1);
                vis[0][i]=vis[1][i+x]=vis[2][i-x+n]=0;
            }
    }


}
int main()
{
    while(~scanf("%d",&n))
    {
        memset(vis,0,sizeof(vis));
        ans=0;
        dfs(0);
        printf("%d\n",ans);
    }
}

打表代码:

#include<cstdio>
#include<string.h>
#define maxn 20
int vis[3][maxn],n,ans;
int dfs(int x)
{
    if(x==2||x==3)
        return 0;
    else if(x==1)
        return 1;
    else if(x==4)
        return 2;
    else if(x==5)
        return 10;
    else if(x==6)
        return 4;
    else if(x==7)
        return 40;
    else if(x==8)
        return 92;
    else if(x==9)
        return 352;
    else if(x==10)
        return 724;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)
            return 0;
        memset(vis,0,sizeof(vis));
        ans=0;
        ans=dfs(n);
        printf("%d\n",ans);
    }
    return 0;
}


0 0
原创粉丝点击