寒假每日一题Week2 day14 AcWing 1432. 棋盘挑战(N皇后问题)

AcWing 1432. 棋盘挑战

题意:

N皇后问题。
每行只可以放一个,每列也只可以放一个。
还要保证对角线不冲突。
输出
按字典序输出前3组答案。
最后输出总方案数。

思路:

首先对于摆放问题
暴力dfs就好,因为行不冲突,所以每行只可以放一个棋子,所以从这里入手
判断冲突的时候要注意一下优化

  1. 暴力查看每一行的每一列,假如当前列 c o l [ i ] col[i] col[i]没有放元素,那么可能可以放。
  2. 之后看是否对角线冲突,可以观察得到
    在这里插入图片描述
    对于每个对左对角线上的值,都是 x − y x-y xy,那么就可以用一个数组,来标记对角线,来防止冲突。(注意x-y,可能出现负数,那么加一个n,防止越界)(右对角线,同理

至于输出
ans<=3时,直接输出即可。

反思:

  1. 本题主要考察对角线上的性质,通过一个数组去判断对角线的冲突。

AC

# include <bits/stdc++.h>
using namespace std;
int ans, n, col[14], ll[30], rl[30];
bool check(int x, int y){
    
    
    if(col[y]||ll[x-y+n]||rl[x+y])return false;
    return true;
}
void dfs(int x){
    
    
    if(x>n){
    
    
        ans++;
        if(ans<=3){
    
    
            int row[14]{
    
    };
            for(int co = 1; co <= n; co++) row[col[co]] = co;
            for(int ro = 1; ro <= n; ro++) cout<<row[ro]<<' ';
            cout<<endl;
        }
        return;
    }
    for(int y = 1; y <= n; y ++ ){
    
    
        if(!check(x,y))continue;
        col[y] = x;
        ll[x-y+n] = rl[x+y] = 1;
        dfs(x+1);
        ll[x-y+n] = rl[x+y] = 0;
        col[y] = 0;
    }
}
int main(){
    
    
    cin>>n;
    dfs(1);
    cout<<ans<<endl;
    return 0;
}

AC2

# include <bits/stdc++.h>
# define mst(x,a) memset(x,a, x)
using namespace std;
int n;
int vis[14], ans;
//vector<vector<int> > res;
int ll[30], rl[30];
bool check(int x, int y){
    
    
    if(ll[x-y+n]||rl[x+y])return false;
    return true;
}
//int path[14][3];

map<vector<int>,int>ma;
void dfs(int x){
    
    
    if(x==n+1){
    
    
        ans++;
       // res.push_back()
       vector<int> res(15);
        for(int i = 1; i <= n; i ++ ) res[vis[i]] = i;
       ma[res] = 1;//cout<<res[i]<<' ';
        //cout<<endl;
        return ;
    }
    for(int y = 1; y <= n; y ++ ){
    
    
        if(vis[y]||!check(x,y))continue;
        vis[y] = x;
        ll[x-y+n] = rl[x+y] = 1;
        dfs(x+1);
        ll[x-y+n] = rl[x+y] = 0;
        vis[y] = 0;
    }
}
int main(){
    
    
    cin>>n;
    dfs(1);
    int cnt = 0;
    for(auto x : ma){
    
    
        if(cnt++ == 3)break;
        auto v = x.first;
        for(int i = 1; i <= n; i ++ )cout<<v[i]<<' ';
        cout<<endl;
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45377553/article/details/112986936