暴力搜索
题目链接:poj-1321 棋盘问题
题目大意:n*n的棋盘上要放k个棋子,棋盘可以放棋子的地方标记为“#”,不能放棋子的地方标记为“.”,问有几种放的方法。
解题思路:dfs搜索,一个关键点是要能想到每行只能放一个棋子,每一列也只能放一个棋子。搜索思路是一行一行搜,写一个check函数检验某个地方能否放棋子(这个地方可以被放棋子,而且该列除了这一行不能放其他棋子)。给每个满足条件的地方放上棋子,继续dfs。遍历完这一行以后,不放棋子的情况dfs,一行一行搜完以后就得到答案。
ac代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
int n,k;
int cnt,ans;
char map[10][10];
int vis[10][10];
bool check(int i,int j) {
if(map[i][j]=='.') return false;
for(int I=0; I<n; I++) {
if(vis[I][j]==1&&I!=i)
return false;
}
return true;
}
bool dfs(int row) {
cout<<"row=="<<row<<"cnt=="<<cnt<<"ans=="<<ans<<endl;
if(cnt==k) {
ans++;
return 0;
}
if(row>=n) return 0;
for(int j=0; j<n; j++) {
if(check(row,j)) {
cnt++;
vis[row][j]=1;
dfs(row+1);
vis[row][j]=0;
cnt--;
}
}
dfs(row+1);
}
int main() {
while(scanf("%d %d",&n,&k)!=EOF) {
if(n==-1&&k==-1) return 0;
cnt=ans=0;
memset(vis,0,sizeof vis);
for(int i=0; i<n; i++)
for(int j=0;j<n;j++) {
cin>>map[i][j];
}
dfs(0);
cout<<ans<<endl;
}
return 0;
}
j
心得体会:所谓dfs搜索关键就是想好怎么搜,心里有那个答案树,把思路想好以后要把每一个步骤转化为代码。看代码的时候也要分块去看,一块一块去看,这一块有什么作用,训练自己把自然语言转化为代码的能力。