#处可以放棋子,每行每列只能放一个,求放k个棋子的方法有多少种,呃,无脑的搜索题,这是深搜回溯的类型。
核心代码
void dfs(int x,int y)
{
int i, j;
if (y == k)
{
ans++;
}
else if (x<=n){
for (i = 1; i <= n; i++)
{
if (!leap[i]&&a[x][i]=='#')
{
leap[i] = 1;
dfs(x + 1, y + 1);
leap[i] = 0;
}
}
if (n - x + y >= k)
dfs(x + 1, y);
}
}
全代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char a[9][9];
int leap[9], n, k;
long long ans;
void dfs(int x,int y)
{
int i, j;
if (y == k)
{
ans++;
}
else if (x<=n){
for (i = 1; i <= n; i++)
{
if (!leap[i]&&a[x][i]=='#')
{
leap[i] = 1;
dfs(x + 1, y + 1);
leap[i] = 0;
}
}
if (n - x + y >= k)
dfs(x + 1, y);
}
}
int main()
{
int i, j, m;
while (scanf("%d%d", &n, &k) != EOF){
getchar(); ans = 0;
if (n == -1 && k == -1)break;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
cin >> a[i][j];
getchar();
}
memset(leap, 0, sizeof(leap));
dfs(1, 0);
cout << ans << endl;
}
return 0;
}
对此类问题的一个总结:
int DFS(当前状态)
{
if (终止条件) return 结果;
for (所有从当前状态能到的状态)
{
if (下一个状态可行)
{
准备工作;
DFS(下一个状态);
清理工作;
}
}
}
还有一种搜索是对这个数列取或不取的搜索,这是一个具体实现(明天补上)
void bfs(int x)
{
if (终止) 执行需要的操作;
else
{
如果取这个数,操作;
bfs(x + 1);
还原;
不取这个数的操作;
bfs(x + 1);
如果这样也能满足条件, 操作;
}
}