搜索5--noi1700:八皇后问题
一、心得
二、题目
1700:八皇后问题
-
总时间限制:
- 10000ms 内存限制:
- 65536kB
-
描述
- 在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。 输入
- 无输入。 输出
- 按给定顺序和格式输出所有八皇后问题的解(见Sample Output)。 样例输入
- 样例输出
-
No. 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 No. 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 No. 3 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 No. 4 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 No. 5 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 No. 6 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 No. 7 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 No. 8 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 No. 9 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 ...以下省略
提示
- 此题可使用函数递归调用的方法求解。 来源
- 计算概论05
三、分析
DFS经典题目
四、AC代码
1 //1700:八皇后问题 2 /* 3 1、首先分析输出样例的顺序 4 选第一行,选第二行 5 按行的顺序 6 说明是指定了列,让我们来填行 7 */ 8 #include <iostream> 9 using namespace std; 10 //用来存储方案 ,下标都是从1开始 11 int a[9][9]; 12 int visRow[9]; //行 13 int visLeftIncline[17];//左斜线 使用的时候 row+column 14 int visRightIncline[16]; //右斜线,使用的时候row-column+8 15 int ansCount=0; 16 17 void init(){ 18 19 } 20 21 void print(){ 22 cout<<"No. "<<(++ansCount)<<endl; 23 for(int i=1;i<=8;i++){ 24 for(int j=1;j<=8;j++){ 25 cout<<a[i][j]<<" "; 26 } 27 cout<<endl; 28 } 29 30 } 31 32 void search(int column){ 33 if(column>8){ 34 //if(ansCount>=5) return; 35 print(); 36 //cout<< ansCount<<endl; 37 } 38 else{ 39 for(int row=1;row<=8;row++){ 40 if(!visRow[row]&&!visLeftIncline[row+column]&&!visRightIncline[row-column+8]){ 41 visRow[row]=1; 42 visLeftIncline[row+column]=1; 43 visRightIncline[row-column+8]=1; 44 a[row][column]=1; 45 search(column+1);//找下一列 46 //回溯 47 visRow[row]=0; 48 visLeftIncline[row+column]=0; 49 visRightIncline[row-column+8]=0; 50 a[row][column]=0; 51 } 52 } 53 } 54 } 55 56 int main(){ 57 init(); 58 search(1); 59 return 0; 60 }
五、注意点
1、注意回溯里面的return
return语句总是返回到调用这个函数的父函数
而在回溯中
所以在最后面层的return是绝对不会影响到其他函数的计算结果和输出结果的
在以后每次输出结果的时候做一个判断,就能控制结果的输出了