n皇后问题

Problem Description:

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

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

Output:

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

1
8
5
0
Sample Output:

1
92
10

思路:
以下图的 4x4 棋盘为例:
这里写图片描述

显然每行棋盘有且仅有一个皇后,所以我们可以依次在第0、1、2、3行放置皇后,每一行再按列放置,每放置一个皇后前判断该位置是否允许放置,每放置一个皇后后将其所在行、列、斜线的棋盘标记为不可放置

由于我们是依次按行放置皇后,所以放置时不需要判断该行是否可放置。

用visy[]数组标记列:vis[i]为1表示第i列不可放置

图中红色的线为主对角线,蓝色的线为副对角线。

可以观察到,每条主对角线上棋盘的行数与列数之差为定值(图中三条主对角线的x-y对应三个值),所以每放置一个皇后,将vis1[x-y]赋值为1(x、y为该皇后所在行、列)。

副对角线上棋盘的行数与列数之和为定值(图中三条副对角线的x+y对应三个值),所以每放置一个皇后,将vis2[x+y]赋值为1。

下面是代码:

#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
int n,ans;
const int maxn=14;
int visy[maxn],vis1[2*maxn];
map<int,int>vis2;
void dfs(int k){
    if(k==n){
        ans++;
        return ;
    }
    for(int i=0;i<n;i++)
    if(!visy[i] && !vis1[k+i] && !vis2[k-i]){
        visy[i]=vis1[k+i]=vis2[k-i]=1;
        dfs(k+1);
        visy[i]=vis1[k+i]=vis2[k-i]=0;
    }
}
int main(){
    while(scanf("%d",&n),n){
        memset(visy,0,sizeof(visy));
        memset(vis1,0,sizeof(vis1));
        vis2.clear();
        ans=0;
        dfs(0);
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值