HDU_2553_N皇后问题

18 篇文章 0 订阅
11 篇文章 0 订阅

经典问题。

但是方案却不唯一,记得很早的时候写过n个循环嵌套的版本。

现在想想蠢死了。

只有八皇后是否在同一直线斜线上判断方法也有多种。

首先一行一行(或者一列一列)填皇后这个应该是没的说的。判断斜线是个要点

法1就是打一个棋盘然后每填上一个皇后就把皇后的攻击范围全部标记。回溯的时候再把皇后的攻击范围全部改回去。

          判断皇后能不能在那个格子很快。但是这个填改的过程应该很慢。

法2就是利用几何关心 n皇后 两个皇后处于左下右上对角线方向x1-x2=y1-y2

                                                                   处于左上右下对角线方向x1-x2=y2-y1

下面这个代码并不能过(TLE)

#include <iostream>
#include <stdio.h>
using namespace std;

const int M=11;
int cb[M];
//int cbz[2M-1],cbf[2M-1];  //主对角线副对角线

int tot;

void dfs(int nnow,int naim)
{
    if(nnow==naim)
        tot++;
    else
    {
        for(int i=0;i<naim;i++)
        {
            int f=1;
            cb[nnow]=i;
            for(int j=0;j<nnow;j++)                                 //坏处就是这个循环 要遍历之前填过的皇后
                if(cb[j]==i||nnow-j==cb[nnow]-cb[j]||nnow-j==cb[j]-cb[nnow])
                {
                    f=0;
                    break;
                }
            if(f)
                dfs(nnow+1,naim);
        }
    }

}

int main()
{
    int n;
    while(1)
    {
        scanf("%d",&n);
        if(!n)
            break;
        tot=0;
        dfs(0,n);
        printf("%d\n",tot);
    }
    return 0;
}
坏处如上 这个方法要遍历填过去的皇后信息进行计算。

法3

#include <iostream>
#include <stdio.h>
using namespace std;

const int M=11;
int cbh[M];               //某行是否使用
int cbz[2*M-1],cbf[2*M-1];  //主对角线副对角线

int re[M];

int tot,n;

void dfs(int nnow)
{
    if(nnow==n)
        tot++;
    else
    {
        for(int i=0;i<n;i++)          //将在nnow列i行放皇后
        {
            int tmp=nnow+n-i;
            if(!cbh[i]&&!cbz[nnow+i]&&!cbf[tmp])
            {
                    cbh[i]=cbz[nnow+i]=cbf[tmp]=1;
                    dfs(nnow+1);
                    cbh[i]=cbz[nnow+i]=cbf[tmp]=0;     //改回来
            }
        }
    }

}

int main()
{
    for(n=1;n<M;n++)                      //TLE的主要原因在此 这个问题必须打表
    {
        tot=0;
        dfs(0);
        re[n]=tot;
    }
    while(1)
    {
        scanf("%d",&n);
        if(!n)
            break;
        printf("%d\n",re[n]);
    }
    return 0;
}
直接利用几何关系,在放置皇后时更新行以及主副对角线信息。

这个题超时的关键在于应该打表。

提示是以后这种答案组数较少但是每组答案计算耗时较长的应该用打表的方法。

另附这个题居然直接这样也可以过……

#include <iostream>
#include <stdio.h>
using namespace std;

const int M=11;

int re[M]={0,1,0,0,2,10,4,40,92,352,724};


int main()
{
    int n;
    while(1)
    {
        scanf("%d",&n);
        if(!n)
            break;
        printf("%d\n",re[n]);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值