AcWing 1432. 棋盤挑戰
阿新 • • 發佈:2021-01-23
技術標籤:Acwing寒假
給定一個N×N的棋盤,請你在上面放置N個棋子,要求滿足:
- 每行每列都恰好有一個棋子
- 每條對角線上都最多隻能有一個棋子
1 2 3 4 5 6 ------------------------- 1 | | O | | | | | ------------------------- 2 | | | | O | | | ------------------------- 3 | | | | | | O | ------------------------- 4 | O | | | | | | ------------------------- 5 | | | O | | | | ------------------------- 6 | | | | | O | | -------------------------
上圖給出了當N=6N=6時的一種解決方案,該方案可用序列2 4 6 1 3 5
來描述,該序列按順序給出了從第一行到第六行,每一行擺放的棋子所在的列的位置。
請你編寫一個程式,給定一個N×N的棋盤以及N個棋子,請你找出所有滿足上述條件的棋子放置方案。
輸入格式
共一行,一個整數N。
輸出格式
共四行,前三行每行輸出一個整數序列,用來描述一種可行放置方案,序列中的第i個數表示第i行的棋子應該擺放的列的位置。
這三行描述的方案應該是整數序列字典序排在第一、第二、第三的方案。
第四行輸出一個整數,表示可行放置方案的總數。
資料範圍
6≤N≤13
輸入樣例:
6
輸出樣例:
2 4 6 1 3 5 3 6 2 5 1 4 4 1 5 2 6 3 4
思路:N皇后問題回溯法,使用三個bool陣列來判斷兩條對角線和列是否滿足條件(此題不用空間換時間會超時)
#include<iostream> #include<memory.h> #include<vector> using namespace std; int n,res; bool visit[3][200]; void dfs(int cnt,vector<int> &col,vector<vector<int> > &ans){ if(cnt==n) {res++;if(res<=3) ans.push_back(col);} else{ for(int i=0;i<n;i++){ if(!visit[0][i] && !visit[1][cnt+i] && !visit[2][cnt-i+n]){ col[cnt]=i; visit[0][i]=visit[1][cnt+i]=visit[2][cnt-i+n]=true; dfs(cnt+1,col,ans); visit[0][i]=visit[1][cnt+i]=visit[2][cnt-i+n]=false; } } } } int main(){ res=0; memset(visit,false,sizeof visit); cin>>n; vector<vector<int> > ans; vector<int> col(n,0); dfs(0,col,ans); for(int i=0;i<3;i++){ for(int j=0;j<n;j++){ cout<<ans[i][j]+1<<' '; } cout<<endl; } cout<<res<<endl; return 0; }