POJ 1321:棋盘问题(DFS)

版权声明:wywwzjj https://blog.csdn.net/weixin_42348709/article/details/83477431

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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;
}
展开阅读全文

没有更多推荐了,返回首页