您的位置:首页 > 其它

N皇后问题 HDU - 2553

2016-12-14 21:39 288 查看
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。 

你的任务是,对于给定的N,求出有多少种合法的放置方法。 

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


Sample Output

1
92
10

思路:明显是用回溯法,这里比较难的是对角线,列的状态表示,列的状态用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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM 搜索 回溯