n皇后问题

n皇后问题:
* 给定一个n*n的棋盘,向该棋盘中放入n个皇后,使得n个皇后之间不在同行同列或同斜线,问有多少种方法
*
* 解题思路:
* 采用深度优先搜索的思想:
* 1.整体上通过按行的思想,从第0行到第n-1行逐层深入进行递归。
* 2.每次递归时要记录之前所有已经放好的皇后的位置,用于接下来判断该行哪些位置能放皇后

 

1.未优化常数的方法

代码及解析:

复制代码
 1 public static int num1(int n) {
 2         if (n < 1) {
 3             return 0;
 4         }
 5         int[] record = new int[n];//开辟用于记录0--n-1行皇后所在列位置的数组空间
 6         return process1(0,record,n);
 7     }
 8     
 9     /*
10      * i表示目前深度优先搜索所寻找到的层数
11      * []record记录了0——i-1层的皇后所在的列数位置
12      * n表示一共要探索的总层数
13      * 返回值:返回可以进行的摆放方式
14      */
15     public static int process1(int i,int[] record,int n) {
16         if (i == n) {//说明0——n-1层的皇后位置都被正常放好,可以返回一种有效的摆放方式
17             return 1;
18         }
19         int ans = 0;
20         for (int k = 0; k < n; k++) {
21             if (isValid(record,i,k)) {//如果在当前i-1层摆放的情况下,第i层第k列允许放一个皇后
22                 record[i] = k;
23                 ans += process1(i+1,record,n);
24             }
25         }
26         return ans;
27     }
28     
29     //判断当前位置能否放入皇后
30     public static boolean isValid(int[] record,int i,int k) {
31         for (int j = 0; j < i; j++) {
32             if (record[j] == k || Math.abs(i - j) == Math.abs(record[j] - k)) {
33                 return false;
34             }
35         }
36         return true;
37     }
复制代码

 

2.优化方法:

优化思路:
* 使用数值中的每一位的0/1来表示皇后位置,第i位为1/0表示第i列有/无皇后
* 所以如果该列有了一个皇后,后续的皇后都不能在这一列。
* 而不能同斜线问题,则用位运算的左移和右移来进行实现

代码及解析:

复制代码
 1 //因为int最大值为2^32 - 1,所以我们讨论不超过32皇后的问题
 2     public static int num2(int n) {
 3         if (n < 1 || n > 32) {
 4             return 0;
 5         }
 6         int limit = 1 << n;//n个皇后只要用n位即可,但int数一共有32位,所以加一个限制条件,让它只用n位
 7         return process2(limit,0,0,0);
 8     }
 9     
10     /*
11      * col用来处理皇后放置问题的列限制,1表示不能放皇后,0则可以
12      * left用来处理皇后放置问题的左斜线限制,1表示不能放皇后,0则可以
13      * right用来处理皇后放置问题的右斜线限制,1表示不能放皇后,0则可以
14      */
15     public static int process2(int limit,int col,int left,int right) {
16         if (col == limit) {//所有列都不能放则说明n个皇后已放满,形成了一个有效的放置情况
17             return 1;
18         }
19         int pos = limit & (~(col | left | right));//得到能放皇后的位置(即所有为1的位置)
20         int ans = 0;
21         while (pos != 0) {
22             int rightOne = pos & (~pos + 1);//获取最右位,从该位(列)开始进行深度搜索
23             pos = pos - rightOne;//因为该列有了皇后,所以对pos进行更新
24             ans += process2(limit,col | rightOne,left | rightOne << 1,right | rightOne >> 1);
25         }
26         return ans;
27     }
复制代码

 

posted @   jue1e0  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示