POJ 1321 棋盘问题(DFS+回溯)

这道题类似于八皇后问题,比较水。

这里记下来是复习一下排列组合和回溯DFS。

#include <iostream> #include <cstring> using namespace std; char g[9][9]; int s[9][2]; int count; int c; int f[9]; bool check(int t) { int i = 0; int x = s[t][0]; int y = s[t][1]; if(g[x][y]=='.') return false; for(i=0;i<t;i++) { if(s[i][0]==x || s[i][1]==y) return false; } return true; } /* //回溯求组合数C(n,k) //这里的h是为了避免重复的组合,区别于排列的求解 //比如求{1,2,3}的C(3,2) //1,2和2,1是重复的 void com(int n,int k,int t,int h) { if(t>k) { c++; return; } int i = 1; for(i=h;i<=n;i++)//下一个元素的回溯选取从剩余的元素开始。比如,当t=1时选了1,可能的组合是1,2和1,3。当回溯时,第一个元素选择2时,第二个元素的选取不能从1开始选,这样会选择重复的2,1,这时第二个元素要从3开始选择。 { if(f[i]==0) { f[i]=1; com(n,k,t+1,i+1); f[i]=0; } } } */ //这里的a类似于求组合数中的h,表示下一个元素的选取应从选‘下一行’开始。 void dfs(int n,int k,int t,int a) { if(t==k) { count++; return; } int i ,j; for(i=0;i<n;i++) for(j=0;j<n;j++) { s[t][0]=i; s[t][1]=j; if(check(t)) { dfs(n,k,t+1,i+1); } } } int main() { int n,k; int i ,j; cin>>n; cin>>k; while(n!=-1 && k!=-1) { count=0; c=0; if(n==0 || k==0) { cout<<0<<endl; } else { count=0; memset(g,0,sizeof(g)); memset(s,1,sizeof(s)); for(i=0;i<n;i++) { getchar(); for(j=0;j<n;j++) g[i][j]=getchar(); } dfs(n,k,0,0); cout<<count<<endl; } cin>>n; cin>>k; } }

你可能感兴趣的:(c,ini)