HDU2553 N皇后 回溯法+打表

点击打开链接

N皇后问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 30795    Accepted Submission(s): 13372

 

Problem Description

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

Input

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

Output

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

Sample Input

1
8
5
0

Sample Output

1
92
10

Author

cgf

Source

2008 HZNU Programming Contest

Recommend

lcy   |   We have carefully selected several similar problems for you:  1016 1312 1181 1010 2614

回溯法:

当把问题分成若干步骤并递归求解时,如果当前步骤没有合法选择,则函数将返回上一级递归调用,这种现象称为回溯。

递归枚举算法的过程中,把生成和检查有机的结合起来,从而减少不必要的枚举,通常称为回溯算法

思路:
恰好每一行放置一个皇后,用c[x]表示第x行皇后的列编号,

则问题变为全排列生成问题,0-7的全排列为8!=40320,枚举量不会超过它

《HDU2553 N皇后 回溯法+打表》

既然是逐行放置的,则皇后肯定不会横向攻击,只需要检查纵向和斜向攻击即可。

条件“ cur-C[cur] == j-C[j] || cur+C[cur] == j+C[j] ” 用来判断皇后 (cur,C[cur]) (j,C[j]) 是否在同一条对角线上。

《HDU2553 N皇后 回溯法+打表》

 求解答案的代码:

#include<bits/stdc++.h>
using namespace std;
//n皇后
int tot;//解的个数
int c[12];//c[x]表示第x行皇后的列编号
void search(int n,int cur)
{
   if(cur==n)//递归边界
        tot++;//只要走到这里,所有皇后必然不冲突
   else
   for(int i=0;i<n;i++){//恰好每行每列各放置一个皇后
    int ok=1;
    c[cur]=i;//尝试把第cur行的皇后放在第i列
    for(int j=0;j<cur;j++)//检查是否与前面的皇后冲突
        if(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])
    {
        ok=0;break;
    }
    if(ok)  search(n,cur+1);//如果合法,则继续递归
   }
}
int main()
{
    /*
    while(cin>>n&&n){
        tot=0;
        search(0);
        cout<<tot<<endl;
    }
    */
    for(int n=0;n<12;n++)
    {
        tot=0;
        search(n,0);
        cout<<tot<<",";
    }
    return 0;
}

AC代码

#include<iostream>
using namespace std;
int main()
{
    int a[]={1,1,0,0,2,10,4,40,92,352,724,2680};
    int n;
    while(cin>>n&&n){
        cout<<a[n]<<endl;
    }
    return 0;
}

 

    原文作者:回溯法
    原文地址: https://blog.csdn.net/qq_40507857/article/details/80418328
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞