POJ 1321 -- 棋盘问题(DFS)
解题思路:
DFS(程序中写成bfs完全手抖笔误...
只有棋盘区域‘#‘可以放棋子,如果棋盘区域的个数sumn与棋子数k相等,那么只有一种摆放方案...
如果sumn>k,则使用dfs进行搜索
设置状态数组bool square[10][10],若是‘#‘则为true,否则为false。
由于棋子都是一样的,摆放没有顺序之分。为了保证每一行只放一个棋子,所以,从第一行开始遍历,查看第一行的所有列,如果有空格,则可以在这个格子中选择放下棋子,同时标记这一列不能再放其他棋子。bool col[10]的下标为列号,放入棋子后,标记该列为false
之后进入下一行...
当剩余棋子数为0时,表明一套摆放方案已经完成,进行回溯...
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 int n,k;///将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目 6 bool square[10][10]; 7 bool col[10]; 8 int ans; 9 void bfs(int x,int num) 10 {///当前考察的为第x行 11 if(num == 0) 12 {///所有棋子已经放置完,成功方案 13 ans++; 14 return; 15 } 16 ///前x行已经决定是否要放棋子 17 for(int i=x+1;i<=n;i++)///行 18 { 19 for(int j=1;j<=n;j++)///列 20 { 21 if(square[i][j] && col[j])///可以放置 22 { 23 square[i][j] = false; 24 col[j] = false; 25 bfs(i,num-1); 26 ///回溯 27 square[i][j] = true; 28 col[j] = true; 29 } 30 } 31 } 32 33 } 34 int main() 35 { 36 while(cin>>n>>k && n!=-1 && k!=-1) 37 { 38 char temp; 39 int sumn=0; 40 memset(square,false,sizeof(square)); 41 memset(col,false,sizeof(col)); 42 for(int i=1;i<=n;i++) 43 for(int j=1;j<=n;j++) 44 { 45 temp = getchar(); 46 while(temp == ‘\n‘) temp = getchar(); 47 if(temp == ‘#‘) 48 { 49 sumn++; 50 square[i][j] = true; 51 col[j] = true;//当前列有空格 52 } 53 } 54 ans = 0; 55 if(sumn == k) 56 cout<<1<<endl; 57 else 58 { 59 bfs(0,k); 60 cout<<ans<<endl; 61 } 62 63 64 } 65 return 0; 66 }