1. 程式人生 > >POJ 1321:棋盤問題(DFS)

POJ 1321:棋盤問題(DFS)

在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放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; }