微信扫一扫打赏支持

搜索5--noi1700:八皇后问题

搜索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是绝对不会影响到其他函数的计算结果和输出结果的

在以后每次输出结果的时候做一个判断,就能控制结果的输出了

posted @ 2017-08-11 20:21  范仁义  阅读(575)  评论(0编辑  收藏  举报