POJ 1321:棋盤問題(DFS)
阿新 • • 發佈:2018-11-04
在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。
棋盤問題
這個題非常經典,細細品嚐,必有所獲。自帶回溯的深搜用起來很愜意。
每次遇到合適的位置,立即鑽進去,轉而進入下一個深搜,直到棋子完全拜完,此深搜結束,回到上一個深搜狀態,再進行恢復現場,恢復完後先到下一列,下一列可行又繼續前面的狀態,換列不能解決就換行,直到行數跑完,行數跑完則結束當前深搜,繼續改變上一個深搜狀態。“第一個”深搜以最後一行作為起點,才真正結束。
#include <cstdio>
using namespace std;
#define sf scanf
#define pf printf
#define rep(i,a,b) for(int i=a;i<(b);++i)
char G[10][10];
bool fg[10] = {0}; // 走過為真
int ans = 0, n, k;
void dfs(int cur, int x) { // cur為已擺的棋子數, x 為行數
if(cur == k) {
ans++;
return;
}
rep(i, x, n)
rep (j, 0, n)
if(G[i][j] == '#' && !fg[j]) {
fg[j] = true;
dfs(cur+1, i+1); // 下一行繼續擺下一個棋子
fg[j] = false;
}
}
int main() {
while(sf("%d%d", &n, &k) == 2 && n != -1 && k != -1) {
rep(i,0,n) sf ("%s",G[i]);
dfs(0, 0); // 第一行開始擺
pf("%d\n", ans); ans = 0;
}
return 0;
}