Codeup 2046 Eight Queens dfs

Portal

First is about ideas

Eight queens problem is a classic dfs, this board is a 8x8 grid map, we come to the diagrams dfs row. Since the subject told the group that only 92 correct answers, while the output is the size of lexicographical inquiry solution, so you can put all 92 solution lexicographical ordering all pre-existing string array, so that answers can be output directly accessed through the index. So how to get this group of 92 solution yet.

string res [100]; // store the results in order to 

Since it is a lexicographic answer, so you can start dfs from column 1, line 1, through each column of the row, then the row and the column where the ranks of all the diagonal mark, followed by dfs row 2, 3 Row. . . . . . .

int book [8] [8]; // for marking 

But here a little skill, you can not tag line is located, because the next line through the rows of markers to determine when there is no relationship with the mark on a line, so long as the mark where the columns and diagonals where he was, as long as the diagonal he marked the beginning of the next line. We can use the line to make the end of the dfs judgment condition, the string when when dfs to eighth row if you can also enter the layer, then the solution is to achieve the ninth row (this figure does not line 9), saved directly this string then return it, each time dfs pass a string when the number of rows and current dfs depth.

. 1  void DFS ( int n-, String T) {// is the number of n-row, t is the acquired character strings lexicographically on line
 2      // this code starting from row 0
 . 3      IF (n-== . 8 ) { // if after line 7, described to obtain a feasible solution, to deposit the solution down 
. 4          RES [CNT ++] = T;
 . 5          return ;
 . 6      }
 7      
. 8      for ( int I = 0 ; I < . 8 ; I ++ ) {/ / traversal column
 . 9          
10          iF (! Book [n-] [I]) {     // determines whether the change point is marked 
. 11              
12 is              for ( int K = n-+. 1 ; K < . 8 ; K ++) {    // mark   
13 is                  Book [K] [I] ++ ;
 14                  IF (I + KN < . 8 ) {          // determines whether bounds 
15                      Book [K] [I + KN] + + ;
 16                  }
 . 17                  iF (I- (KN)> = 0 ) {       // determines whether the cross-border 
18 is                      Book [K] [I- (KN)] ++ ;
 . 19                  }
 20 is              }
 21 is              
22 is              DFS (n-+ . 1 , T + char (I + 49)); // number of rows and the string of the current transmission dfs depth.
23 is              
24              for ( int K = n-+ . 1 ; K < . 8 ; K ++) {   // back 
25                  Book [K] [I] - ;
 26 is                  IF (I + KN < . 8 ) {        
 27                      Book [K] [I + KN ] - ;
 28                  }
 29                  IF (I- (KN)> = 0 ) {
 30                      Book [K] [I- (KN)] - ;
 31 is                  }
 32              }
 33 is          }
 34 is      }
 35 }

 

这里做标记的时候没有让book数组直接等于一个数而是让他自增自减是因为后面做的标记可能会和前面做的标记重叠,后面行的对角线标记和前面行的行标记重叠,自增自减就可以避免回溯去标记的时候把前面行的标记去掉,这里的对角线标记是通过这些变量的关系从下一行开始以所在列为基准依次+1或-1获取列(并且判断是否越界)的。

附上完整AC代码

#include<iostream>
using namespace std;


string res[100];  //用来按顺序存放结果 
int book[8][8];  //用来做标记 
int cnt=0;       

void dfs(int n,string t){
    
    if(n==8){ //如果过了第7行,说明得到一个可行解,把这个解存下来 
        res[cnt++]=t;
        return;
    }
    
    for(int i=0;i<8;i++){
        
        if(!book[n][i]){    //判断改点是否被标记 
            
            for(int k=n+1;k<8;k++){   //做标记  
                book[k][i]++;
                if(i+k-n<8){         //判断是否越界 
                    book[k][i+k-n]++;
                }
                if(i-(k-n)>=0){      //判断是否越界 
                    book[k][i-(k-n)]++;
                }
            }
            
            dfs(n+1,t+char(i+49));
            
            for(int k=n+1;k<8;k++){  //回溯 
                book[k][i]--;
                if(i+k-n<8){        
                    book[k][i+k-n]--;
                }
                if(i-(k-n)>=0){
                    book[k][i-(k-n)]--;
                }
            }
        }
    }
}




int main(){
    int n;
    cin>>n;
    string t;
    dfs(0,t);//从第0行开始dfs,开始传递一个空的字符串 
    
    while(n){
        n--;
        int t;
        cin>>t;
        cout<<res[t-1]<<endl;//直接输出答案 
    }
    
    return 0;
} 

ACM小白,第一次写题解,有诸多不足,欢迎指正。

Guess you like

Origin www.cnblogs.com/anitena/p/11299997.html