码迷,mamicode.com
首页 > 其他好文 > 详细

POJ-1321.棋盘问题.(回溯解决)

时间:2019-03-04 13:00:47      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:while   gif   一个   --   简单的   cstring   图片   show   棋盘问题   

    做完题之后看了网上的一些题解但是发现他们的解释大部分都是错误的,所以就自己写了一下,笔者能力也有限,有错误之处大家多多指正。

    第一次看题的时候以为就是简单的八皇后,但是写了之后发现存在很多问题,比如需要记录放入的棋子数,在一次访问之后没有回复原来棋盘的形状等一些问题。

  本题思路:

    回溯思想,对于每一行,从这一行的第一个开始放棋子,如果发现棋子可以放就放下一个棋子并且将已经放了棋子的数目更新,如果某一次放的棋子数目已经达到题目要求个数,则回溯到这一行的其它列并回复原来的状态继续放棋子,直到所有情况都放完为止,这里需要特别注意的是每次放棋子要改变对应列的状态和放的棋子个数,但是当回溯到这个对其它列进行操作的时候需要将这两个状态都更新为上一个状态即放这个棋子之前的状态,最后记得需要多后面的每行进行统计,因为棋子可能不是从第一行开始放的。

  

技术图片
 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int maxn = 8;
 6 int n, k, ans, count;
 7 char maze[maxn][maxn];
 8 bool isvisited[maxn];//表示某一列是否被访问
 9 
10 void dfs(int u) {
11     if(count == k) {
12         ans ++;
13         return;
14     }
15     if(u >= n) return;
16     for(int v = 0; v < n; v ++) {
17         if(maze[u][v] == # && !isvisited[v]) {
18             count ++;//更新放了这个棋子之后的状态
19             isvisited[v] = true;
20             dfs(u + 1);
21             count --;//更新到放这个棋子之前的状态
22             isvisited[v] = false;
23         }
24     }
25     dfs(u + 1);//棋子的起始行可能不是第一行
26 }
27 
28 int main () {
29     while(~scanf("%d %d", &n, &k)) {
30         if(n == -1 && k == -1)  break;
31         memset(isvisited, false, sizeof(isvisited));
32         ans = count = 0;
33         getchar();
34         for(int i = 0; i < n; i ++) {
35             for(int j = 0; j < n; j ++) {
36                 maze[i][j] = getchar();
37             }
38             getchar();
39         }
40         dfs(0);
41         printf("%d\n", ans);
42     }
43     return 0;
44 }
View Code

 

POJ-1321.棋盘问题.(回溯解决)

标签:while   gif   一个   --   简单的   cstring   图片   show   棋盘问题   

原文地址:https://www.cnblogs.com/bianjunting/p/10469935.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!