题目链接:http://poj.org/problem?id=1321
package Search;
import java.util.*;
public class POJ1321 {
static int c;//结果
static int n,k;
static boolean[][] map;//用数组来标记地图形状
static boolean[] used;//标记器
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
c = 0;
n = sc.nextInt();
k = sc.nextInt();
if(n==-1 && k==-1)return;
map = new boolean[n+1][n+1];
used = new boolean[n+1];
for(int i = 1; i<=n;i++){
String temp = sc.next();
for(int j = 0;j<n;j++){
char ch = temp.charAt(j);
if(ch=='#')map[i][j+1] = true;
}
}
dfs(1,0);//从第一行开始搜索,开始的时候搜索到的棋子为0,注意这里的初始值。
System.out.println(c);
}
}
//逐行搜索,row为当前搜索行,num为已填充的棋子数
private static void dfs(int row, int num) {
if(num == k){//如果填充的棋子满了,表示搜索结束
c++;
return;
}
if(row>n)return;//搜索越界,搜索结束
for(int i = 1;i<=n;i++){
if(map[row][i] && !used[i]){
used [i] = true;//标记该行已经放置棋子
dfs(row+1,num+1);
used [i] = false;//回溯
}
}
dfs(row+1,num);//这里是难点,当k<n时,row在等于n之前就可能已经把全部棋子放好
//又由于当全部棋子都放好后的某个棋盘状态已经在前面循环时记录了
//因此为了处理多余行,令当前位置先不放棋子,搜索在下一行放棋子的情况
return;
}
}