棋盘问题-简单搜索练习

来源:互联网 发布:three.js加载3d模型 编辑:程序博客网 时间:2024/06/06 00:33

POJ1321(DFS棋盘问题)


解题报告:
1.题意很简单,一个棋盘问题,可以用搜索方式解决。那么好,它的搜索框架很明晰了,从一个状态到下一个搜索状态,直到数目达到K,计数加一,或者此搜索状态无解,回溯。

显然,搜索退出条件是数目达到K或者此搜索状态无解。


2.状态如何表示?

vis[i][j]标记是否有落子即可。再简单一点,采取按行搜索的顺序,在当前行row下,只需记录col[j]是否有落子即可。


3.状态如何转移?

在当前行row下,已经落子cnt,那么可以就当前行是否落子转移到下一个状态。

有两种可能,(1)要么不落子,直接搜索下一行row+1;(2)要么遍历所有列,可以落子则落子


//DFS#include <cstdio>#include <string>#include <algorithm>using namespace std;const int maxn = 9;bool col[9];char map[9][9];int N, K, ans;bool dfs(int cnt, int row)//cnt已落子数,row当前行数{if (cnt == K) return true;if (row >= N) return false; if (dfs(cnt, row + 1)) ans ++;//该行不落子for (int j = 0; j < N; j++)//如果条件允许该行落子{if (!col[j] && map[row][j] == '#')//允许条件,j列无子,棋盘可落子{col[j] = 1;if (dfs(cnt + 1, row + 1)) ans ++;col[j] = 0;}}return false;}int main(){while (scanf("%d%d%*c", &N, &K) != EOF && (N != -1 || K != -1)){for (int i = 0; i < N; i++)gets(map[i]);ans = 0;memset(col, 0, sizeof(col));dfs(0,0);printf("%d\n", ans);}return 0;}
                                             
0 0