标签:
题意:
Input
Output
Sample Input
2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1
Sample Output
2 1
思路分析:
DFS方法。
1、从第一个棋子开始放,能放的棋子必须满足条件:在棋盘区域&&这个位置没被放过,按照这个条件把棋子依次放下去,每放一颗棋子记得:
(1)标记这个位置
(2)已放棋子数要加加
2、一旦遇到放不下去的棋子,就回溯到上一个棋子。此时:
(1)撤销上次被标记的位置
(2)已放棋子数要减减
3、判断越界是否可以结束。越界条件:
(1)已放棋子数=要求放的棋子数
(2)棋子数超过了棋盘区域
源代码:
1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 using namespace std; 5 char chess[12][12]; 6 int vis[12]; 7 int n,k,sum,ans; 8 void dfs(int a) 9 { 10 11 if (ans == k) //已放棋子数=给定的棋子数 12 { 13 sum++; 14 return; 15 } 16 if (a >= n) //棋子数超过棋盘区域 17 return; 18 19 for (int j = 0; j < n; j++) 20 { 21 if (chess[a][j] == ‘#‘&&!vis[j]) 22 { 23 vis[j] = 1; //标记位置已被放过 24 ans++; //已放棋子数加加 25 dfs(a + 1); //放下一个棋子 26 vis[j] = 0; //撤销标记,递归失败 27 ans--; //已放棋子数减减 28 } 29 30 } 31 dfs(a + 1); //放第二行棋子 32 } 33 int main() 34 { 35 while (cin >> n >> k) 36 { 37 sum = 0; //方案数 38 ans = 0; //已放棋子数 39 getchar(); 40 if (n == -1 && k == -1) 41 break; 42 memset(chess, 0, sizeof(chess)); 43 memset(vis, 0, sizeof(vis)); 44 for (int i = 0; i < n; i++) 45 { 46 for (int j = 0; j < n; j++) 47 cin >> chess[i][j]; 48 getchar(); 49 } 50 dfs(0); 51 cout << sum << endl; 52 } 53 54 return 0; 55 56 }
心得:
本题跟八皇后的问题相似,都是DFS,回溯,但是有些细节不一样,比如越界条件。第二次遇到这种题目还是有些恍惚,可能是没有理解透吧。。。。。↖(^ω^)↗加油
标签:
原文地址:http://www.cnblogs.com/Lynn0814/p/4690393.html