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;
}