n 皇后问题

 

  问题描述:在n×n格的棋盘上放置彼此不受攻击的n个皇后。即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


    思路:每个皇后都是放在单独的一行,因此同行就不用判断了。用一个数组记录每个皇后可能的列位置,比如Col[0]表示皇后0所在的列号,0到 n-1 之间的值。对于每一种排列,检查是否有在同一列或者同一对角线的两个皇后。产生全排列的算法可以参考字符串的排列。

    这种方法很简单,但是效率太低了。可以改进一下,采用回溯的思想。首先考虑皇后0所在的列号,取0到7的一个。然后考虑皇后1,检查每一个可能的列号,如果与皇后0没有冲突,那么考虑皇后2;如果与皇后0有冲突,那么直接返回,继续考虑已经没有意义。

    参考代码:NQueenProblem(8)计算8后问题

  1. //函数功能 : 检查皇后cur的摆法  
  2. //函数参数 : n为皇后数,cur为当前检查的皇后,col为皇后的列位置,sum为找到的摆法  
  3. //返回值 :   无  
  4. void Queen(int n, int cur, int *col, int *sum)  
  5. {  
  6.     if(cur == n)  //找到一种摆法  
  7.     {  
  8.         for(int i = 0; i < n; i++)  
  9.             cout<<col[i]<<' ';  
  10.         cout<<endl;  
  11.         (*sum)++; //摆法加1  
  12.         return;  
  13.     }  
  14.     int i, j;  
  15.     for(i = 0; i < n; i++) //考虑每一个可能的列号  
  16.     {  
  17.         //检查当前考虑的皇后是不是可以放在位置i  
  18.         for(j = 0; j < cur; j++)  
  19.         {  
  20.             if(abs(j-cur) == abs(col[j]-i) || col[j] == i) //与之前的皇后有冲突,不用考虑下一个皇后了  
  21.                 break;  
  22.         }     
  23.         if(j == cur)   
  24.         {  
  25.             col[cur] = i;  //可以放在这个位置  
  26.             Queen(n, cur+1, col, sum); //考虑下一个皇后  
  27.         }  
  28.     }  
  29. }  
  30.   
  31. //函数功能 : n皇后的摆法  
  32. //函数参数 : n为皇后数  
  33. //返回值 :   摆法的数量  
  34. int NQueenProblem(int n)  
  35. {  
  36.     int *col = new int[n];  
  37.     int sum = 0;  
  38.     Queen(n, 0, col, &sum); //调用核心函数  
  39.     delete [] col;  
  40.     col = NULL;  
  41.     return sum;  
  42. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值