查找到问题,暂停600毫秒,
穷举本行,200毫秒
返回上一层之前,会弹出回滚上一层(4,X),并暂停600毫秒
成功返回时,会弹出上一层具体数据如(4,3)然后又暂停600毫秒
#include <iostream>
#include <windows.h>
using namespace std;
int q[100];
int count=0;void dispasolution(int n)
{count++;cout<<"第"<<count<<"个解";for(int i=0; i<=n; i++){cout<<"("<<i<<","<<q[i]<<")";}cout<<endl;
}bool place(int i,int j)
{if(i==1){return true;}int k=1;while(k<i) // 1-i 行检查 ,因为每行放一个 ,所以 i 是 k 的界限{if((q[k]==j)||(abs(q[k]-j)==abs(i-k))) // 这一行的皇后纵坐标是 j, 这一列有皇后就不能放。对角线即正方形,即行的距离和列的距离不能一样{return false;}k++;}return true; // 穷举完发现正常,才退出}void show(int n)
{for(int i=1; i<=n; i++){for(int j=1; j<=n; j++){if(q[i]==j) cout<<"X";else cout<<"O";}cout<<endl;}
}void queen(int i,int n)
{char a[n+1][n+1]= {"O"};for(int i=1; i<=n; i++){for(int j=1; j<=n; j++){if(q[i]==j) a[i][j]='X';else a[i][j]='O';}cout<<endl;}if(i>n){system("cls");show(n);dispasolution(n);cout<<"发现一个解,如上图"<<endl;Sleep(2000);}else{for(int j=1; j<=n; j++) // 从 j=1 开始,在第 i 行试探每一列 j{if(place(i,j)) // 如果成了,就记录通过检查的列{q[i]=j;for(int k=1; k<=n; k++)a[i][k]='O';a[i][j]='X';system("cls");for(int i=1; i<=n; i++){for(int k=1; k<=n; k++)cout<<a[i][k];cout<<endl;}cout<<"发现检查列的合适点""("<<i<<","<<j<<")"<<",开始进入下一层"<<endl;Sleep(600);queen(i+1,n);cout<<"本行穷举完毕,正在回滚上一层""("<<i<<","<<j<<")"<<endl;Sleep(600);}else{a[i][j]='*';system("cls");for(int i=1; i<=n; i++){for(int k=1; k<=n; k++)cout<<a[i][k];cout<<endl;}cout<<"正在穷举本行"<<"("<<i<<","<<j<<")"<<endl;Sleep(200);}}cout<<"本行穷举完毕,正在回滚上一层""("<<i-1<<","<<"X"<<")"<<endl;Sleep(600);}
}int main()
{int n=0;cout<<"n皇后问题(n<20)n="<<n<<endl;cin>>n;if(n>20) cout<<"n值太大,不能求解"<<endl;else{cout<<n<<"皇后问题求解问题如下"<<endl;queen(1,n);}}