深搜DFS
POJ-1321
Input
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
Sample Input
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
Sample Output
2
1
#include<cstdio>
#include<cstring> const int maxn=; char board[maxn][maxn]; //记录棋盘状态
int place[maxn]; //记录一列是否已经放过棋子
int n,k;
int cnt,num; //cnt 是放棋子的方案数 ,num是已放棋子数目 void DFS(int i){
if(num==k){
cnt++;
return ;
}
if(i>=n)
return ;
for(int j=;j<n;j++) {
if(!place[j] && board[i][j]=='#'){
place[j]=;
num++;
DFS(i+);//cnt计数操作
place[j]=;
num--;
}
}
DFS(i+); //i行不放棋子,进入下一行操作
} int main(){ //freopen("input.txt","r",stdin); int i,j;
while(scanf("%d%d",&n,&k)){
getchar();
if(n==- && k==-)
break;
for(i=;i<n;i++){
for(j=;j<n;j++)
scanf("%c",&board[i][j]);
getchar();
}
memset(place,,sizeof(place));
cnt=;
num=;
DFS();
printf("%d\n",cnt);
}
return ;
}
对于这个问题,怎说呢,对于初学者来说还是有难度的,因为搞不清楚递归函数的入口和出口,很容易弄混淆。
这里先说一下大体的思路吧,对于上边的那个四四的棋盘来说,首先从1 4进去,然后再在1 4里面进入2 3,然后进入3 2,然后进入4 1,然后从num的判断条件返回,cnt++。
凡是从num返回的都是可行的方案,因为棋子数达到了最大,而且是在满足题目要求的条件下。所以num返回才是正道。而从n的判断条件返回的就都不是什么好货了。因为当从n返回的时候,i都是大于n的,这是因为上一行已经不放棋子了,所以后面无论怎么放,都不可能放下。
也就是说,从1 4 进去这条路的意思是,先确定1 4,然后接着确定其它的棋子位置,但是这条路走完之后,第一行已经无立锥之地放棋了,所以,接着又进入2 3,顺着 2 3进入 3 2,然后是 4 1,从n返回。这时候判断的就是第一行不放棋子,然后让后几行放入棋子的情况。这样的话,肯定是不会满足条件的。
之后顺次进入第三行第四行,然后第五行退出。
细说的话,实际上刚才已经将清楚了,现在一行里面判断一轮,能放棋的地方都是一条路。这里可以模拟一下一行有两块棋盘的情况,当有两块棋盘的时候,你就会发现place在这里的作用了,因为只有!place【j】满足的条件下才能进入对这一条路的判断,虽然这一条路可以放两个棋子,但是你会发现这抵触了题目的条件,单行单列单棋子。就这样。
深搜DFS的更多相关文章
- 图的遍历 之 深搜dfs
DFS 遍历 深度优先搜索是一个递归过程,有回退过程. 对一个无向连通图,在访问图中某一起始顶点u 后,由u 出发,访问它的某一邻接顶点v1:再从v1 出发,访问与v1 邻接但还没有访问过的顶点v2: ...
- HDU 2553 N皇后问题(深搜DFS)
N皇后问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 深搜(DFS),Image Perimeters
题目链接:http://poj.org/problem?id=1111 解题报告: 1.这里深搜有一点要注意,对角线上的点,如果为'.',则total不应该增加,因为这不是他的边长. #include ...
- 深搜(DFS),回溯,Fire Net
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=2 解题报告: 这里的深搜有一点不同,就是,在深搜每一个点时,都要深搜每 ...
- 算法学习笔记(六) 二叉树和图遍历—深搜 DFS 与广搜 BFS
图的深搜与广搜 复习下二叉树.图的深搜与广搜. 从图的遍历说起.图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其 ...
- 【深搜(DFS)-例题-踏青】-C++
描述 小白和他的朋友周末相约去召唤师峡谷踏青.他们发现召唤师峡谷的地图是由一块一块格子组成的,有的格子上是草丛,有的是空地.草丛通过上下左右 4 个方向扩展其他草丛形成一片草地,任何一片草地中的格子都 ...
- 【LeetCode】深搜DFS(共85题)
[98]Validate Binary Search Tree [99]Recover Binary Search Tree [100]Same Tree [101]Symmetric Tree [1 ...
- HDU 2614 Beat 深搜DFS
这道题目还是比较水的,但是题意理解确实费了半天劲,没办法 谁让自己是英渣呢! 题目大意: 猪脚要解决问题, 他有个习惯,每次只解决比之前解决过的问题的难度要大. 他给我们一个矩阵 矩阵的 i 行 j ...
- noj电子老鼠走迷宫(深搜dfs)超时错误
1042.电子老鼠闯迷宫 时限:1000ms 内存限制:10000K 总时限:3000ms 描述 有一只电子老鼠被困在如下图所示的迷宫中.这是一个12*12单元的正方形迷宫,黑色部分表示建筑物,白色 ...
- poj1321 棋盘问题(深搜dfs)
转载请注明出处:http://blog.csdn.net/u012860063? viewmode=contents 题目链接:id=1321">http://poj.org/prob ...
随机推荐
- 百度之星资格赛 1004 度度熊的午饭时光(01背包+最小序号和+字典序+有bug)
分析 首先声明一下,我的代码有漏洞的,求大神给个正确代码 思路如下: 首先做一遍01背包记录路径并求出最大总分,令path[i][j]表示第i个物品包含在dp[j]的求值过程中.再逆序枚举money, ...
- Codeforces510B【dfs】
判断一个图里是否有一个自环: 50*50 标记起点,然后暴搜? #include <bits/stdc++.h> #include<algorithm> using names ...
- linux 问题一 apt-get install 被 lock
问题: sudo apt-get install vim E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporari ...
- 洛谷P2569 [SCOI2010]股票交易(单调队列)
传送门 惭愧……这种题目都没看出来…… 首先,我们用$dp[i][j]$表示在第$i$天,手上有$j$股时的最大收益 第一,我们可以直接买股票,即$dp[i][j]=-j*AP_i$,这个直接计算即可 ...
- 如何访问google?
1:浏览器打开 uzer.me 网站(建议:火狐,不行就谷歌) 2:点击注册,注册一个账号 3:登录账号,进入如下界面,选择火狐浏览器 4:这样就可以进行国外的网站访问了
- c++模板专门化
#include <iostream> #include<cstring> using namespace std; template <typename T> T ...
- 7.1 Java集合概述
List 有序.重复的集合 Set 无序.不可重复的集合 Map 具有映射关系的集合 jdk1.5之后.Java增加了Queue体系集合,代表一种队列集合实现
- 521 Longest Uncommon Subsequence I 最长特殊序列 Ⅰ
给定两个字符串,你需要从这两个字符串中找出最长的特殊序列.最长特殊序列定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列).子序列可以通过删去字符串中的某些字符实现,但不能改变剩余 ...
- oracle PL、SQL(概念)
一.PL/SQL简介. Oracle PL/SQL语言(Procedural Language/SQL)是结合了结构化查询和Oracle自身过程控制为一体的强大语言,PL/SQL不但支持更多的数据类型 ...
- 协程和I/O模型
1.协程: 单线程实现并发 在应用程序里控制多个任务的切换+保存状态 优点: 应用程序级别速度要远远高于操作系统的切换 缺点: 多个任务一旦有一个阻塞没有切换,整个线程都阻塞在原地 该线程内的其他的任 ...