hdu_2553

http://acm.hdu.edu.cn/showproblem.php?pid=2553


分析:模板题,但是一不小心就TLE了,所以还是打个表比较放心。



代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
#define  MM -1000

int a[12];     //一维数组表示棋盘
int ans[12];   //打表

void init()
{
    for(int i=0;i<12;i++) a[i]=MM;
}

bool valid(int row, int col, int e)
{
    for (int i = 0; i < e; i++){
        if (a[i] == col || abs(i - row) == abs(a[i] - col))
            return false;
    }
    return true;
}

int queen(int e)
{
    int cnt = 0;
    int i = 0, j = 0;
    while (i < e){
        while (j < e){             //对i行的每一列进行探测,看是否可以放置皇后
            if(valid(i, j, e))      //该位置可以放置皇后
            {
                a[i] = j;        //第i行放置皇后
                j = 0;           //第i行放置皇后以后,需要继续探测下一行的皇后位置,所以此处将j清零,从下一行的第0列开始逐列探测
                break;
            }
            else  j++;
        }
        if(a[i] == MM){         //第i行没有找到可以放置皇后的位置
            if (i == 0)  break;           //回溯到第一行,仍然无法找到可以放置皇后的位置,则说明已经找到所有的解,程序终止
            else {
                j = a[--i] + 1;        //把上一行皇后的位置往后移一列
                a[i] = MM;      //把上一行皇后的位置清除,重新探测
                continue;
            }
        }
        if (i == e - 1)          //最后一行找到了一个皇后位置,说明找到一个结果,打印出来
        {
            cnt++;
            j = a[i] + 1;             //从最后一行放置皇后列数的下一列继续探测
            a[i] = MM;           //清除最后一行的皇后位置
            continue;
        }
        i++;
    }
    return cnt;
}

void deal()   //预处理,先将答案放在数组里
{
    for(int i=1;i<11;i++){
        init();
        ans[i]=queen(i);
    }
}

int main()
{
    freopen("in.txt","r",stdin);
    deal();
    int n;
    while(scanf("%d",&n)!=EOF){
         if(n==0)  break;
         printf("%d\n",ans[n]);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值