http://poj.org/problem?id=1321
题意 : 我能说这是迄今为止见到的POJ上第二道中文题吗,既然是中文也很好理解,就不详述了
思路 : 典型的深搜DFS ;
#include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 100 ; int vis[maxn] ; int ch[maxn][maxn] ; int cnt = 0 ,n,k ; int judge(int a,int b)//判断这个棋子的这一行和这一列是否还有别的可以放棋子的地方 { for(int i = 1 ; i <= n ; i++) { if(ch[a][i] == -1) return 0 ; if(ch[i][b] == -1) return 0 ; } return 1 ; } void dfs(int step,int col)//step代表的是步数,col代表着是放了棋子的个数 { if(col == k) { cnt++ ; return ; } if(step == n*n) return ; int a = step/n+1 ;//现在棋子所在位置的行和列 int b = step%n+1 ; if(ch[a][b]&&judge(a,b))//这个点是#号并且这个点所在的行和列没有别的#了 { ch[a][b] = -1 ;//代表着#这个点已经放上了 dfs(step+1,col+1) ; ch[a][b] = 1 ;//表示那一种已经操作完毕,恢复原样,找下一种方法 } dfs(step+1,col) ;//因为放法有很多种,所以可以本来的这里不放放下一个 return ; } int main() { while(~scanf("%d %d",&n,&k)) { if(n == -1&&k == -1) break ; cnt = 0 ; char sh ; memset(ch,0,sizeof(ch)) ; for(int i = 1 ; i <= n ; i++) { for(int j = 1 ; j <= n ; j ++) { cin>>sh ; if(sh == '#') ch[i][j] = 1 ;//#标记为1代表是可以放棋子的 } } dfs(0,0) ; cout<<cnt<<endl ; } }