8皇后问题

  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

  

Code:
  1. #include <iostream>  
  2. #include <math.h>  
  3. using namespace std;  
  4. int c[9] = {0};  
  5. int count = 0;  
  6.   
  7. void print();  
  8. bool judge(int);  
  9.   
  10. void eight_queens(int n)  
  11. {  // 求解函数  
  12.   if(n == 9) //递归边界  
  13.    {  
  14.        count++;  
  15.        print();  
  16.        cout << "/n";  
  17.    }  
  18.   else  
  19.    {  
  20.     for(int i = 1; i <= 8; i++)  
  21.        {  
  22.        c[n] = i; //a[n]是列,n是行   
  23.        if(n == 1)//如果是第一行  
  24.          {  
  25.          c[n] = i;//试当前 i 列  
  26.           eight_queens(n + 1);  
  27.            }  
  28.         else //如果不是第一行则判断满足条件不  
  29.          if(judge(n))  
  30.             eight_queens(n + 1);//满足条件才排下一位  
  31.        }  
  32.    }  
  33. }  
  34.   
  35. bool judge(int n)  
  36. // 判断一个位置是否合法  
  37.     int i;  
  38.     for(i = 1 ; i < n; i++)  
  39.          if(c[n] == c[i] || abs(c[n]-c[i]) == abs(n-i))  
  40.               return false;  
  41.     return true;  
  42. }  
  43.   
  44. void print()  
  45. // 打印棋盘  
  46.     for ( int i = 1;i <= 8; i++)  
  47.     {  
  48.         for (int j = 1; j <= 8; j++)  
  49.         {  
  50.             if (c[i] == j)cout << "@ ";  
  51.             else cout << "# ";  
  52.             if (j == 8)cout << "/n";  
  53.         }  
  54.     }  
  55. }  
  56.   
  57. void main()  
  58. {  
  59.     eight_queens(1);  
  60.     printf("/n共有%d个解",count);  
  61. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值