这道题并不是很难,但由于惯性思维,会考虑dirx[]、diry[]进行位置的点变换,但发现这样子并不很容易就能递归出来。
这一题用的行列变换,这道题的价值就在于开拓思维,并不在于难度。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10;
char maps[maxn][maxn];
int vis[maxn];
int n, k;
int ans;
void dfs(int x, int cnt){ //x 遍历行,cnt棋子个数
if(cnt == k) {
//printf("#1 ");
ans++; return ;
}
if(x > n) return ; //2个if顺序不能交换 ,对应dfs(x+1, cnt)
for(int i = 1; i <= n; i++){ //列变换
if(maps[x][i] =='#' && !vis[i]){
// printf("#3 ");
vis[i] = 1;
dfs(x+1,cnt+1);
vis[i] = 0;
//printf("#4 ");
}
}
// printf("#2 ");
dfs(x+1, cnt); //就是说 如果有4个地方可以放旗子,但只有2个棋子,就需要这一步,同时对应第二个if
//可以做个实验把注释掉的全部取消注释,并把if交换顺序,试一下就知道了
return;
}
int main(){
while(scanf("%d%d", &n, &k) != EOF){
if(n==-1&&k==-1) break;
ans = 0;
int cnt1 = 0;
for(int i = 1; i <= n; i++){
scanf("%s", &maps[i][1]);
for(int j = 1; j <= n; j++){
if(maps[i][j] == '#')
cnt1++;
}
}
memset(vis, 0, sizeof(vis));
if(cnt1==k){
printf("1\n");
}
else {
dfs(1,0);
printf("%d\n", ans);
}
}
return 0;
}
poj 1321 棋盘问题 dfs
最新推荐文章于 2022-07-04 09:14:17 发布