n皇后问题

n皇后问题:在一个n*n的国际象棋棋盘上放置n个皇后,使得这n个皇后两两均不在同一行、同一列、同一条对角线上,求合法的方案数。

解法:将其看成全排列问题,生成n的全排列,可确保其均不在同一行、同一列,接下来就是判断每两个皇后是否在同一条对角线上,利用count计数,合法的排列则使count加1,最后输出count。

朴素法代码如下:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 const int maxn = 11;
 4 int n, P[maxn], hashTable[maxn] = {false};
 5 int count = 0;
 6 void generateP(int index)
 7 {
 8     if(index == n+1)
 9     {
10         bool flag = true;
11         for(int i = 1; i <= n; i++)
12         {
13             for(int j = i+1; j <= n; j++)
14             {
15                 if(abs(i - j) == abs(P[i] - P[j]))
16                 {
17                     flag = false;
18                 }
19             }
20         }
21         if(flag)
22         {
23             count ++;
24         }
25         return;
26     }
27     for(int x = 1; x <= n; x++)
28     {
29         if(hashTable[x] == false)
30         {
31             P[index] = x;
32             hashTable[x] = true;
33             generateP(index+1);
34             hashTable[x] = false;
35         }
36     }
37 }
38 int main()
39 {
40     n = 8;
41     generateP(1);
42     printf("%d", count);
43     return 0;
44 }

 枚举所有情况计算量较大,事实上,可以发现,当已经放置了一部分皇后时(对应于已经生成排列的一部分时),可能剩余的皇后无论怎样放置都不可能合法,因此在排列的过程中进行检验,若有在同一对角线的元素,则停止递归,减少计算量。

采用回溯法的代码如下:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 const int maxn = 11;
 4 int n, P[maxn], hashTable[maxn] = {false};
 5 int count = 0;
 6 void generateP(int index)
 7 {
 8     if(index == n+1)
 9     {
10         count++;
11         return;
12     }
13     for(int x = 1; x <= n; x++)
14     {
15         if(hashTable[x] == false)
16         {
17             bool flag = true;
18             for(int pre = 1; pre < index; pre++) //遍历之前的皇后
19             {
20                 //第index列皇后的行号为x,第pre列皇后的行号为P[pre]
21                 if(abs(index - pre) == abs(x - P[pre]))
22                 {
23                     flag = false;
24                     break;
25                 }
26             }
27             if(flag)
28             {
29                 P[index] = x;
30                 hashTable[x] = true;
31                 generateP(index + 1);
32                 hashTable[x] = false;
33             }
34         }
35     }
36 }
37 int main()
38 {
39     n = 8;
40     generateP(1);
41     printf("%d", count);
42     return 0;
43 }

 

转载于:https://www.cnblogs.com/narnia/p/11250143.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值