↓這題目較為複雜,當延伸閱讀就好
a160: 祖靈想要下棋!!!!!!!!
https://zerojudge.tw/ShowProblem?problemid=a160
內容 :
從前有一個很會數學又很會寫程式的小小高中生。他的名子叫祖靈。 他很愛下西洋棋,有一天他在寫程式的時候剛好碰到了一種同樣有關西洋棋的題目。就是傳說中初學者在學DFS的時候一定要學的東西。就是"八皇后"。 他遇到了困難,寫不出來。請各位好心人寫一個程式幫幫他。
範例輸入
1
2
3
4
0
範例輸出
Q
1
0
0
xQxx
xxxQ
Qxxx
xxQx
xxQx
Qxxx
xxxQ
xQxx
2
8*8棋盤的8皇后問題解答共92種,消除一些旋轉或翻轉後重複的答案後,剩12種,如下
位置(x,y) 的 x-y 表示了主對角線
位置(x,y) 的 x+y 表示了副對角線
解答
#include<iostream>
using namespace std;
const int MAX_N=12;
int N = MAX_N;
int ansNum; //有幾種解
int column[MAX_N] = {0}; // 同行是否有皇后 ↑↓
int slash[2 * MAX_N] = {0}; // 右上至左下是否有皇后?↙
int backSlash[2 * MAX_N] = {0}; // 左上至右下是否有皇后 ↘
int queens[MAX_N] = {0};
//檢查這一格是否可以放下皇后,可以回傳true
int isVisitable(int y, int x) {
return !(column[x] || slash[x + y] || backSlash[x - y + N]);
}
//印出棋盤結果
void print() {
int x, y;
for(y = 0; y < N; y++) {
for(x = 0; x < N; x++) {
cout<<(queens[y] == x ? "Q" : "x");
}
cout<<endl;
}
cout<<endl;
}
//找尋可以放皇后的格子
void dfs( int y) {//i是第幾隻皇后,同時也是第幾列
if(y >= N) { //已放好第8隻皇后
print(); //印出正解
ansNum++;
}
else {
int x;
for(x = 0; x < N; x++) {
if(isVisitable(y, x)) { //這格能不能放皇后
queens[y] = x;
column[x] = slash[x + y] = backSlash[x - y + N] = 1; //將皇后放下去,所以不能放的地方增加了
dfs( y + 1 ); //往下一列,繼續尋找皇后的擺放點
column[x] = slash[x + y] = backSlash[x - y + N] = 0; //將皇后拿起來,所以不能放的地方減少了
}
}
}
}
int main(void) {
while(cin>>N&&N!=0){
ansNum = 0;
dfs(0); //0代表放了幾隻皇后,每一行都會有一隻,且只能有一隻
cout<<ansNum<<endl;
}
return 0;
}