八皇后问题(n皇后问题):递归和非递归的解法(C++)

 八皇后问题:在8*8格的棋盘上,放8个皇后,任意两个皇后不能在同一行,同一列,同一斜线上,求有几种摆法

 n皇后问题:在n*n格的棋盘上,放n个皇后,任意两个皇后不能在同一行,同一列,同一斜线上,求有几种摆法

 

  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <fstream>
  4. using namespace std;
  5. //非递归
  6. void queen(int n)
  7. {
  8.     int *c=new int [n];//记录列状态
  9.     int *d1=new int[2*n-1];//记录正对角线状态
  10.     int *d2=new int[2*n-1];//记录负对角线状态
  11.     int *lc=new int[n];//记录皇后在第n放的列数
  12.     
  13.     int **Queen=new int *[n];//棋盘
  14.     for(int i=0;i<n;i++)//初始化
  15.     {
  16.         Queen[i]=new int[n];
  17.         for(int j=0;j<n;j++)
  18.         {
  19.             Queen[i][j]=0;
  20.         }
  21.         c[i]=0;
  22.         d1[i]=0;
  23.         d1[2*n-i-2]=0;
  24.         d2[i]=0;
  25.         d2[2*n-i-2]=0;
  26.     }
  27.     
  28.     
  29.     int line=0;//行
  30.     int column=0;//列
  31.     __int64 num=0;//可以摆放的数量
  32.     __int64  count=0;//循环次数
  33.     
  34.     while(line>=0)
  35.     {
  36.         while(column<n)
  37.         {
  38.             
  39.             count++;
  40.             if(c[column]==0&&d1[line-column+n-1]==0&&d2[line+column]==0)//如果列,正负对角线都没有放,则为真
  41.             {
  42.                 
  43.             
  44.                     
  45.                     if(line==n-1)//如果到最后一行,则为真
  46.                     {
  47.                         Queen[line][column]=1;
  48.                         num++;//摆放数量加1
  49.                         Queen[line][column]=0;
  50.                         
  51.                         
  52.                         break;
  53.                         
  54.                     }
  55.                     else
  56.                     {
  57.                         //记录摆放状态
  58.                         Queen[line][column]=1;
  59.                         c[column]=1;
  60.                         d1[line-column+n-1]=1;
  61.                         d2[line+column]=1;
  62.                         lc[line]=column;
  63.                     
  64.                         line++;//进入下一行,从第0列开始
  65.                         column=0;
  66.                     }
  67.             }
  68.             else
  69.                 column++;
  70.         }
  71.         count++;
  72.         //如果这一行,所有格都不能放,则退一行,则从上一行上次摆放的下一列开始遍历
  73.         line--;
  74.         if(line>=0)
  75.         {
  76.             
  77.             column=lc[line];
  78.             Queen[line][column]=0;
  79.             c[column]=0;
  80.             d1[line-column+n-1]=0;
  81.             d2[line+column]=0;
  82.             column++;
  83.             
  84.         
  85.             
  86.             
  87.         }
  88.         
  89.         
  90.     }
  91.     cout<<num<<'/t'<<count<<endl;;
  92.         
  93.     
  94. }
  95. //递归
  96. void queen1(int i,int**Queen,int *a,int *d1,int *d2,int& n,int &QueenNumber,__int64&count)
  97. {
  98.     
  99.     int iColumn;
  100.     for(iColumn=0;iColumn<n;iColumn++)
  101.     {
  102.         count++;
  103.         if(a[iColumn]==0&&d1[i-iColumn+n-1]==0&&d2[i+iColumn]==0)
  104.         {
  105.             Queen[i][iColumn]=1;
  106.             a[iColumn]=1;
  107.             d1[i-iColumn+n-1]=1;
  108.             d2[i+iColumn]=1;
  109.             if(i<n-1)
  110.                 queen1(i+1,Queen,a,d1,d2,n,QueenNumber,count);
  111.             else
  112.             {
  113.                 QueenNumber++;
  114.                 /*
  115.                 fstream outstuf;
  116.                 outstuf.open("out.txt",ios::out|ios::app);
  117.                 for(int i=0;i<8;i++)
  118.                 {
  119.                     for(int j=0;j<8;j++)
  120.                     {
  121.                         outstuf<<Queen[i][j]<<" ";
  122.                     }
  123.                     outstuf<<"/r/n";
  124.                 }
  125.                 outstuf<<"/r/n";
  126.                 outstuf.close();*/
  127.             }
  128.             
  129.             Queen[i][iColumn]=0;
  130.             a[iColumn]=0;
  131.             d1[i-iColumn+n-1]=0;
  132.             d2[i+iColumn]=0;
  133.         }
  134.     }
  135. }
  136. void queendg(int n)
  137. {
  138.     int *c=new int [n];
  139.     int *d1=new int[2*n-1];
  140.     int *d2=new int[2*n-1];
  141.     
  142.     int **Queen=new int *[n];
  143.     for(int i=0;i<n;i++)
  144.     {
  145.         Queen[i]=new int[n];
  146.         for(int j=0;j<n;j++)
  147.         {
  148.             Queen[i][j]=0;
  149.         }
  150.         c[i]=0;
  151.         d1[i]=0;
  152.         d1[2*n-i-2]=0;
  153.         d2[i]=0;
  154.         d2[2*n-i-2]=0;
  155.     }
  156.     int QueenNumber=0;
  157.     __int64 count=0;
  158.     queen1(0,Queen,c,d1,d2,n,QueenNumber,count);
  159.     cout<<QueenNumber<<'/t'<<count<<endl;;
  160. }
  161. int _tmain(int argc, _TCHAR* argv[])
  162. {
  163.     
  164.     queendg(8);
  165.     queen(8);
  166.     
  167.     return 0;
  168. }

经测试

queen(16)共14772512种放法,用时206秒

queendg(16)共14772512种放法,用时248秒

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值