HDU 2553 N皇后问题 (状压+dfs)

21 篇文章 0 订阅

N皇后问题

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 18785 Accepted Submission(s): 8510

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

Author
cgf

Source
2008 HZNU Programming Contest

旧题新做呀。大一的时候就用dfs写过当时好像状态记录弄得很复杂。最近学了状压就用状压的思维写了一波。
status用来记录每列是否已经有旗子,另外还有left,right用来记录对角线不能有俩的情况。其实对角线可以这么考虑:对于左对角线来说每往下一行就是left>>1,同理右对角线也是类似的。就记录这三个状态瞎搞一下就行了。在网上有看到别人用位运算不需要先离线答案,我这个代码蜜汁需要离线,不然也是TLE,求大神帮忙看看是为什么。

#include "cstring"
#include "cstdio"
#include "string.h"
#include "iostream"
using namespace std;
int n;
int ans;
void dfs(int row,int status,int left,int right)
{
    if(row>n)
    {
        ans++;
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(((1<<(n-i))&left)||((1<<(n-i))&right))
            continue;

        if((status&(1<<(n-i)))==0)
        {
            int newleft=(left)|(1<<(n-i));
            newleft>>=1;
            int newright=(right)|(1<<(n-i));
            newright<<=1;
            dfs(row+1,status|(1<<(n-i)),newleft,newright);
        }
    }
    return ;

}
int final_ans[20];
int main()
{
    for(int i=1;i<=10;i++)
    {
        n=i;
        ans=0;
        dfs(1,0,0,0);
        final_ans[i]=ans;
    }
    while(~scanf("%d",&n)&&n!=0)
        printf("%d\n",final_ans[n]);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值