类似八皇后, 但是比八皇后(目前还不能完全理解)简单,一眼看出是dfs, 可是不知道如何递归实现,参考了网上的代码。
我们认定从第一行开始找点, 所以每行每行找(row+1),不会出现同行, 我们在弄个列标的标记数组,防止同列。
然后通过回溯令之前走过的标记还原,
#include <iostream>
#include <iomanip>
#include <cstring>
#include <map>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <set>
#include <iomanip>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
using namespace std;
const int N = 10;
const int inf = 0x3f3f3f3f;
typedef long long LL;
int vis[N], col[N];
char G[N][N];
int n, k, status;
void dfs(int row, int num)
{
if(num == k)
{
status++;
return ;
}
if(row > n-1)//防数组越界
return ;
for(int j = 0;j<n;j++)
{
if(G[row][j]&&!vis[j])
{
vis[j]= 1;
dfs(row+1, num+1);
vis[j] = 0;//每一次回溯访问标志重置一次, 走过的路变成没走过的了;
}
}
dfs(row+1, num);//从下一行开始重新寻找解,这两步回溯好难想到。
}
int main()
{
char c;
while(scanf("%d %d", &n, &k), k!=-1&&n!=-1)
{
memset(G, 0, sizeof(G));
for(int i = 0;i<n;i++)
{
getchar();
for(int j = 0;j<n;j++)
{
scanf("%c", &c);
if(c =='#')
G[i][j] = 1;
}
}
memset(vis, 0, sizeof(vis));
status = 0;
dfs(0, 0);//从第一行开始
printf("%d\n", status);
}
return 0;
}