kuangbin带你飞——专题一 简单搜索(1)
题目来源:POJ 1321 棋盘问题
题解
经典棋盘问题,我用的是DFS(深度优先搜索)
,按照行的规律,依次遍历,用vis(标记数组)
标记已经被棋子占据的列。
当k(棋子数目)
等于0时,sum(方案数)
加1。
AC代码
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
int n, k;
// 方案数 sum
ll sum = 0;
// 地图数组 mp , 1 表示 # , 0 表示 .
int mp[10][10];
// 标记数组 vis , 1 表示该列被棋子占据
bool vis[10];
// dfs 代码
void dfs(int l)
{
// 当 k == 0 时,sum + 1 , 并且回溯
if (k == 0)
{
++sum;
return;
}
// 当 l 超出边界时, 回溯
if (l > n)
return;
// 遍历 l 行中每一个数
for (int i = 1; i <= n; ++i)
{
// 如果为 # , 并且该列未被棋子占据
if (mp[l][i] == 1 && vis[i] == 0)
{
// 落子
vis[i] = 1;
--k;
// 搜索下一行
dfs(l + 1);
// 回溯后恢复数据
++k;
vis[i] = 0;
}
}
// 如果该行未落子,仍然搜索下一行
dfs(l + 1);
// 回溯
return;
}
int main()
{
// 多组数据
while (~scanf("%d%d", &n, &k))
{
// 初始化数组
memset(mp, 2, sizeof(mp));
memset(vis, 1, sizeof(vis));
// 去除输入中 \n
cin.get();
if (n == -1 && k == -1)
break;
sum = 0;
// 输入数据,并对数据进行转换
// . -> 0 , # -> 1
char c;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
scanf("%c", &c);
if (c == '.')
mp[i][j] = 0;
else
mp[i][j] = 1;
}
scanf("%c", &c);
}
dfs(1);
printf("%lld\n", sum);
}
return 0;
}