题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2553
N皇后问题Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
Input 共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output 共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input 1 8 5 0 Sample Output 1 92 10 |
#include<stdio.h>
#include<cmath>
using namespace std;
int row[11];//第i行皇后在第row[i]列
int num=0;//记录方案数量
int n;
void queen(int i){
int j,k;
if(i==n){//n个皇后都已经找好位置
num++;
return;
}
for(j=0;j<n;j++){//从第0列开始找位置
for(k=0;k<i;k++)//第i行之前的都已经找好位置
if(row[k]==j||abs(k-i)==abs(row[k]-j))//冲突,跳出循环,测试下一个位置
break;
if(k==i){//没有跳出,则不冲突
row[k]=j;//记录下这个位置
queen(i+1);
}
}
}
int main(){
while(~scanf("%d",&n)&&n!=0){
queen(0);//从第0行的皇后开始找位置
printf("%d\n",num);
num=0;
}
return 0;
}
注意:已经定义为全局变量,当心不要在函数中进行二次定义,从而引起结果错误。
此代码使用的为递归回溯法,现阶段还无法自己组织语言将回溯的过程表达出来,应继续做这类题来加以体会。
这是在其他博客上看到的,感觉对回溯法的使用很有帮助。
原文链接:https://blog.csdn.net/charles1e/article/details/51646879
- 递归回溯框架
int a[n];
try(int i)
{
if(i>n)
输出结果;
else
{
for(j = 下界; j <= 上界; j=j+1) // 枚举i所有可能的路径
{
if(fun(j)) // 满足限界函数和约束条件
{
a[i] = j;
... // 其他操作
try(i+1);
回溯前的清理工作(如a[i]置空值等);
}
}
}
}
递归往往超时,在HDU上不能通过,只能打表。
AC代码如下:
#include<stdio.h>
int main(){
int n;
int a[11]={1,0,0,2,10,4,40,92,352,724};
while(~scanf("%d",&n)&&n!=0){
printf("%d\n",a[n-1]);
}
return 0;
}