洛谷 P1219 八皇后 回溯

回溯法:递归构造中,生成和检查过程相结合,递归函数不再递归调用它自身 而是返回上一层调用 

 Dfs:

八皇后:在n×n的棋盘放置n个棋子,使得每行、每列、每对角线都只有一个棋子。

          图片来自洛谷

输入格式

一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。

输出格式

前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

输入输出样例

输入 #1
6
输出 #1
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

 题解 一:仅使用一个一维数组判断标记是否起冲突 

 1 void search(int cur){           
 2     if(cur==n) {      
 3         sol++;
 4         return;    
 5     }
 6     else for(int i=1;i<=n;i++){               
 7         int ok=1;
 8         c[cur]=i;              //尝试将第cur行的皇后放置在第i列   ==> 逐行放置 因此不需要判断 行冲突
 9         for(int j=1;j<=cur;j++){
10             if(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j]) {        
11                 ok=0;
12                 break;
13             }
14             if(ok) search(cur+1);    
15         }
16     }
17 }

题解 二 :使用一个二维数组判断标记是否起冲突

 1 void search(int cur){
 2     if(cur>n) {
 3         sol++;
 4     } 
 5     else {
 6         for(int i=1;i<=n;i++){
 7         if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]){    //vis[][]分别表示 列与对角线的冲突
 8             c[cur]=i;
 9             vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
10             search(cur+1);
11             vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;      //恢复成上一状态
12             }
13         }
14     }
15 }

 完整代码

#include<iostream>
using namespace std;
int n,sol=0,c[15],vis[3][225];
void search(int cur){
    if(cur>n) {
        sol++;
        if(sol<=3){
            for(int i=1;i<=n;i++){
                cout<<c[i]<<" ";
            }
            cout<<endl;
        }
    } 
    else {
        for(int i=1;i<=n;i++){
        if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]){
            c[cur]=i;
            vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
            search(cur+1);
            vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;
            }
        }
    }
}

int main(){
    cin>>n;
    search(1);
    cout<<sol;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/jjjjjjy/p/11272201.html