http://poj.org/problem?id=1321
分析:
搜索结束条件是已将k个棋子放置完毕。继续搜索的条件是满足如果当前位置上可以放置棋子且不与前面已经放置的棋子同列
(对于同行判断,因为搜索时按行递增所以不会出现同行的情况)。另外对于当前行来说,在它之下的行都有可能放置棋子,所以需要两重循环。
这题是简单的搜索题,主要练习了回溯的用法。
二维数组g的-1表示空白区域,0表示可以放置棋子,1表示已经放置棋子,而在judge判断中一开始用了if(g[i][y]) ,该判断包括除0以外的所有情况所以也包括了-1的情况。
代码:
//poj 1321
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int n,k;
int ans;
int g[10][10];
bool judge(int x,int y)
{
for(int i=0;i<x;i++){
if(g[i][y]==1) return false;
}
return true;
}
void dfs(int r,int num)
{
if(num==0){
ans++;
return;
}
for(int i=r;i<n;i++){
for(int j=0;j<n;j++){
if(!g[i][j] && judge(i,j)){
g[i][j]=1; num--;
dfs(i+1,num);
g[i][j]=0; num++;
}
}
}
return;
}
int main()
{
freopen("in.txt","r",stdin);
char c;
while(cin>>n>>k){
if(n+k == -2) break;
memset(g,-1,sizeof(g));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>c;
if(c=='#') g[i][j]=0; //0 stands for the chess-board
}
}
ans=0;
dfs(0,k);
cout<<ans<<endl;
}
return 0;
}