1. 程式人生 > 其它 >Problem:棋盤挑戰

Problem:棋盤挑戰

技術標籤:演算法c++

Problem Description

給定一個 N × N 的棋盤,請你在上面放置 N 個棋子,要求滿足:

  • 每行每列都恰好有一個棋子
  • 每條對角線上都最多隻能有一個棋子
    在這裡插入圖片描述

上圖給出了當 N = 6 時的一種解決方案,該方案可用序列 2 4 6 1 3 5 來描述,該序列按順序給出了從第一行到第六行,每一行擺放的棋子所在的列的位置。

請你編寫一個程式,給定一個 N×N 的棋盤以及 N 個棋子,請你找出所有滿足上述條件的棋子放置方案。

Input Format

共一行,一個整數 N。

Output Format

共四行,前三行每行輸出一個整數序列,用來描述一種可行放置方案,序列中的第 i 個數表示第 i 行的棋子應該擺放的列的位置。

這三行描述的方案應該是整數序列字典序排在第一、第二、第三的方案。

第四行輸出一個整數,表示可行放置方案的總數。

* Scope of Data*

6 ≤ N ≤ 13

Sample Input

在這裡插入圖片描述

Sample Output

在這裡插入圖片描述

Idea

運用DFS思想從第1行開始對每一列進行列舉判斷

Program Code

 #include <iostream>
 #include <algorithm>

 using namespace std;

 #define x row
 #define y column
 #define P primary_diagonal
 #define
S secondary_diagonal
const int N = 15; int n; int cnt, a[N]; //cnt表示可通過方案數,a[N]表示具體方案 int col[N], P[2 * N], S[2 * N]; //在n * n矩陣中,斜率為1的對角線有2n - 1條,斜率為-1的對角線亦然 void bfs(int x) //定義深搜函式 { if(x > n) //表示最後一行也得到結果,生成完整的一組方案 { cnt ++; //更新方案個數 if(cnt <= 3) //輸出前3個方案 {
for(int i = 1; i <= n; ++ i) cout << a[i] << ' '; cout << endl; } } for(int y = 1; y <= n; ++ y) //每行從第1列開始列舉列 { if(!col[y] && !P[x + y] && !S[x -y + n]) //若該列、主對角線和副對角線均沒有違規(x - y + n 是為防止出現負數,運用了移碼的思想) { a[x] = y; //將列值賦值給對應的答案陣列 col[y] = P[x + y] = S[x -y + n] = 1; //更新相應陣列 bfs(x + 1); //遞迴執行下一行 //恢復現場 a[x] = col[y] = P[x + y] = S[x -y + n] = 0; } } } int main() { cin >> n; //輸入 bfs(1); //從第一行開始執行函式 cout << cnt; //輸出總結果 return 0; }
  • If you have any questions,please feel free to communicata with me.