经典八皇后
题目描述:
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法!
这道题,很明显的回溯法
回溯法的的精髓说白了就是要有一个状态标志,然后根据这标志来决定,下一步走不走.
这里这个标志我们选用一个n*n的二维数组
#include"iostream" using namespace std; int a[100][100],ans; const int n=8; int check(int x,int y){
//检查当前皇后的位置(x,y)与其他皇后有冲突吗 // printf("正在检查%d行,%d列\n",x,y); int i,j; for(i=1;i<=n;i++) if(a[i][y]==1)//判断同行同列有没有皇后 return 0; //判断对角线 for(i=x,j=y;i>=1&&j>=1;i--,j--)//当前位置的左上, if(a[i][j]==1) return 0; for(i=x,j=y;i>=1&&j<=n;i--,j++)//右上位置 if(a[i][j]==1) return 0; return 1; } void print(){ int i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) cout<<a[i][j]<<" "; cout<<endl; } cout<<endl; } void dfs(int row){ // cout<<"行:"<<row<<endl; int i; if(row>n){//递归结束,进行结果的输出 ans++;//解的个数 print(); return ; } for(i=1;i<=n;i++){ //检查 if(check(row,i)){//检查当前位置可用不可用 // printf("第%d行,%d列可以用\n",row,i); a[row][i] = 1;//标记第row行第i列 dfs(row+1);//进入下一行 a[row][i] = 0; //这一步是最关键的一步,状态回溯,将之前的标志取消 } } } int main(){ cout<<"开始执行--------"<<endl; dfs(1); cout<<ans<<endl; }
2020年5月1日21:22:55增加:
可以对标志数组进行压缩,压缩成一维数组
#include<iostream> using namespace std; int a[10],count; const int n =8; void print(){ for (int i = 0; i <= n; i++) { int inner; for (inner = 1; inner <= a[i]; inner++) cout << "0 "; cout <<"K "; for (inner = a[i] + 1; inner <= n; inner++) cout << "0 "; cout << endl; } cout << "==========================\n"; } int check(int index,int loop){ int data,index_pre; //index loop表示当前第index个皇后所在列为loop //data index_pre表示前index个皇后所在列为data for(index_pre=1;index_pre<index;index_pre++){ //data表示前面皇后所在的列,index_pre表示前面的第index_pre个皇后 data = a[index_pre]; //判断是否在同一列 if(loop==data){ return 0; } //判断当前皇后的右上角//右下角 (1,3)和(0,4) 3+1==0+4 if((index+loop)==(index_pre+data)) return 0; //判断当前皇后的左下角 (1,3)和(2,4) 3-1==4-2 if((loop-index)==(data-index_pre)) return 0; } return 1; } void eightQueue(int index){ for(int loop=1;loop<=n;loop++){ if(check(index,loop)){ a[index] = loop; if(index==n){ count++; print(); a[index] = 0;//回溯 return; } eightQueue(index+1); a[index] = 0; //回溯 } } } int main(){ eightQueue(1); cout<<"总计:"<<count<<endl; }

浙公网安备 33010602011771号