Description:八皇后问题,是一个古老而著名的问题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使 其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可 以解决此问题。
Input: null.
Output:按给定顺序和格式输出所有八皇后问题的解。
问题简化,考虑一个4×4的棋盘,由于没有两个皇后能处在同一行,所以每个皇后都在不同的行上。又因为每行有四个位置,就有4^4种可能,每种可能的布局可用有4个分量的向量x={x1,x2,x3,x4}来描述。如果在某行上没有皇后,则相应的分量为0(因此并不明确的包含在向量中)。实际上,因为没有皇后能放在同一列上,一个合法的放置对应于数1,2,3,4的一个排列,这吧搜索空间从4^4减少到4!。
在算法中,我们用术语“合法”来表示一个互不攻击的4个皇后的放置,用术语“部分”;来表示一个互不攻击的少于4个的皇后的放置。显而易见,放在位置xi和xj的两个皇后当且仅当xi=xj时处在同一列上,不难看出两个皇后处在同以对角线上当且仅当
xi - xj = i - j or xi - xj = j - i(i, j = 1,2,3,4)
即一个“合法”的放置应满足
|xi - xj| ≠ |i - j| and xi ≠ xj (i, j = 1,2,3,4)
算法 4-QUEEN
Four_queens (n)
1. C[1…4] ← 0 // 没有皇后放置在棋盘上
2. if n = = 4 // n为带放置皇后的行数 递归边界
3. count++; // count 计算解得个数
4. 输出结果,打印棋盘
5. end if
6. else
7. for k ← 1 to 4
8. C[n] ← k; // 第n 行尝试在第k列放置皇后
9. If n == 1 // 如果是第一行
10. C[c] ← k; // 尝试当前i列
11. 递归 Four_queens (n+1) // 放置下一行
12. end if
13. else if judge(n) //如不是第一行,判断当前尝试是否合法
14. 递归 Four_queens (n+1)
15. end if
16. end for
17. End
- #include <iostream>
- #include <math.h>
- using namespace std;
- int c[9] = {0};
- int count = 0;
- void print();
- bool judge(int);
- void eight_queens(int n)
- { // 求解函数
- if(n == 9) //递归边界
- {
- count++;
- print();
- cout << "/n";
- }
- else
- {
- for(int i = 1; i <= 8; i++)
- {
- c[n] = i; //a[n]是列,n是行
- if(n == 1)//如果是第一行
- {
- c[n] = i;//试当前 i 列
- eight_queens(n + 1);
- }
- else //如果不是第一行则判断满足条件不
- if(judge(n))
- eight_queens(n + 1);//满足条件才排下一位
- }
- }
- }
- bool judge(int n)
- { // 判断一个位置是否合法
- int i;
- for(i = 1 ; i < n; i++)
- if(c[n] == c[i] || abs(c[n]-c[i]) == abs(n-i))
- return false;
- return true;
- }
- void print()
- { // 打印棋盘
- for ( int i = 1;i <= 8; i++)
- {
- for (int j = 1; j <= 8; j++)
- {
- if (c[i] == j)cout << "@ ";
- else cout << "# ";
- if (j == 8)cout << "/n";
- }
- }
- }
- void main()
- {
- eight_queens(1);
- printf("/n共有%d个解",count);
- }

被折叠的 条评论
为什么被折叠?



