基础深搜小结

目前看来,简单深搜题大致分为三类题型:

1是连通块问题,求连通块大小和数量。

2是迷宫问题,问地图内放几个坐标,有几个放法。

3是输出路径问题。

1.这个问题的经典例题是计算水塘(pku-2386 lake counting)

例题:

Due to recent rains, water has pooled in various places in Farmer John‘s field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water (‘W‘) or dry land (‘.‘). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors.

Given a diagram of Farmer John‘s field, determine how many ponds he has.

Input

* Line 1: Two space-separated integers: N and M

* Lines 2..N+1: M characters per line representing one row of Farmer John‘s field. Each character is either ‘W‘ or ‘.‘. The characters do not have spaces between them.

Output

* Line 1: The number of ponds in Farmer John‘s field.

Sample Input

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

Sample Output

3

Hint

OUTPUT DETAILS:

There are three ponds: one in the upper left, one in the lower left,and one along the right side.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int M = 111;
char map[M][M];
int d1[M]={1,1, 1,-1,-1,-1,0, 0};
int d2[M]={0,1,-1, 0,-1, 1,1,-1};
int m,n;
void dfs(int x,int y){
	map[x][y]=‘.‘;
	for(int i=0;i<=7;i++){
		int tx=x+d1[i];
		int ty=y+d2[i];
		if(tx>=0&&tx<=m&&tx>=0&&ty<=n&&map[tx][ty]==‘W‘){
			dfs(tx,ty);
		}
	}
	return ;
}
int main(){
	while(cin>>m>>n){
		int res=0;
		for(int i=1;i<=m;i++){
			for(int j=1;j<=n;j++){
				cin>>map[i][j];
			}
		}
		for(int i=1;i<=m;i++){
			for(int j=1;j<=n;j++){
				if(map[i][j]==‘W‘){
				dfs(i,j); res++;
			}
			}
		}
		cout<<res<<endl;
	}
	return 0;
}

  这题的思路就是在主函数写个for循环,先找到满足条件的点,以此为起点,对所有接下来的点进行深搜,搜索过的点

要记得计数和标记(因为只是计数,不是记录可能性,所以不需要回溯)。

 2.迷宫类问题一般都是用几个数组记录条件,每走一遍就判断数组中是否已经标记过这行或这列。

例题:

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

Input

输入含有多组测试数据。 
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 
当为-1 -1时表示输入结束。 
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

Output

对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

Sample Input

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output

2
1
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int M = 11;
char map[M][M];
int vis[M];
int res=0,flag=0;
int n,k;
void dfs(int row){
    if(flag==k) {res++; return ;}
    if(row>n) return;
    for(int i=1;i<=n;i++){
        if(map[row][i]==‘#‘&&!vis[i]){
            vis[i]=1;
            flag++;
            dfs(row+1);
            vis[i]=0;
            flag--;
        }
    }
    dfs(row+1);
}
int main(){
    while(cin>>n>>k){
        memset(vis,0,sizeof(vis));
        if(n==-1&&k==-1) break;
        res=0;flag=0;
        for(int i=1;i<=n;i++){
            for(int k=1;k<=n;k++){
                cin>>map[i][k];
            }
        }
        dfs(1);  //从第一行开始
        cout<<res<<endl;
    }
    return 0;
}

  3.简单的路径输出其实就是每深搜一步,就用数组记录一下当前值,判断搜到最后一步后,将数组遍历输出即可。

例题:hdu-2181 哈密顿绕行世界问题

一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市。

Input前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出. 
Output输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.参看Sample output 
Sample Input

2 5 20
1 3 12
2 4 10
3 5 8
1 4 6
5 7 19
6 8 17
4 7 9
8 10 16
3 9 11
10 12 15
2 11 13
12 14 20
13 15 18
11 14 16
9 15 17
7 16 18
14 17 19
6 18 20
1 13 19
5
0

Sample Output

1:  5 1 2 3 4 8 7 17 18 14 15 16 9 10 11 12 13 20 19 6 5
2:  5 1 2 3 4 8 9 10 11 12 13 20 19 18 14 15 16 17 7 6 5
3:  5 1 2 3 10 9 16 17 18 14 15 11 12 13 20 19 6 7 8 4 5
4:  5 1 2 3 10 11 12 13 20 19 6 7 17 18 14 15 16 9 8 4 5
5:  5 1 2 12 11 10 3 4 8 9 16 15 14 13 20 19 18 17 7 6 5
6:  5 1 2 12 11 15 14 13 20 19 18 17 16 9 10 3 4 8 7 6 5
7:  5 1 2 12 11 15 16 9 10 3 4 8 7 17 18 14 13 20 19 6 5
8:  5 1 2 12 11 15 16 17 18 14 13 20 19 6 7 8 9 10 3 4 5
9:  5 1 2 12 13 20 19 6 7 8 9 16 17 18 14 15 11 10 3 4 5
10:  5 1 2 12 13 20 19 18 14 15 11 10 3 4 8 9 16 17 7 6 5
11:  5 1 20 13 12 2 3 4 8 7 17 16 9 10 11 15 14 18 19 6 5
12:  5 1 20 13 12 2 3 10 11 15 14 18 19 6 7 17 16 9 8 4 5
13:  5 1 20 13 14 15 11 12 2 3 10 9 16 17 18 19 6 7 8 4 5
14:  5 1 20 13 14 15 16 9 10 11 12 2 3 4 8 7 17 18 19 6 5
15:  5 1 20 13 14 15 16 17 18 19 6 7 8 9 10 11 12 2 3 4 5
16:  5 1 20 13 14 18 19 6 7 17 16 15 11 12 2 3 10 9 8 4 5
17:  5 1 20 19 6 7 8 9 10 11 15 16 17 18 14 13 12 2 3 4 5
18:  5 1 20 19 6 7 17 18 14 13 12 2 3 10 11 15 16 9 8 4 5
19:  5 1 20 19 18 14 13 12 2 3 4 8 9 10 11 15 16 17 7 6 5
20:  5 1 20 19 18 17 16 9 10 11 15 14 13 12 2 3 4 8 7 6 5
21:  5 4 3 2 1 20 13 12 11 10 9 8 7 17 16 15 14 18 19 6 5
22:  5 4 3 2 1 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5
23:  5 4 3 2 12 11 10 9 8 7 6 19 18 17 16 15 14 13 20 1 5
24:  5 4 3 2 12 13 14 18 17 16 15 11 10 9 8 7 6 19 20 1 5
25:  5 4 3 10 9 8 7 6 19 20 13 14 18 17 16 15 11 12 2 1 5
26:  5 4 3 10 9 8 7 17 16 15 11 12 2 1 20 13 14 18 19 6 5
27:  5 4 3 10 11 12 2 1 20 13 14 15 16 9 8 7 17 18 19 6 5
28:  5 4 3 10 11 15 14 13 12 2 1 20 19 18 17 16 9 8 7 6 5
29:  5 4 3 10 11 15 14 18 17 16 9 8 7 6 19 20 13 12 2 1 5
30:  5 4 3 10 11 15 16 9 8 7 17 18 14 13 12 2 1 20 19 6 5
31:  5 4 8 7 6 19 18 17 16 9 10 3 2 12 11 15 14 13 20 1 5
32:  5 4 8 7 6 19 20 13 12 11 15 14 18 17 16 9 10 3 2 1 5
33:  5 4 8 7 17 16 9 10 3 2 1 20 13 12 11 15 14 18 19 6 5
34:  5 4 8 7 17 18 14 13 12 11 15 16 9 10 3 2 1 20 19 6 5
35:  5 4 8 9 10 3 2 1 20 19 18 14 13 12 11 15 16 17 7 6 5
36:  5 4 8 9 10 3 2 12 11 15 16 17 7 6 19 18 14 13 20 1 5
37:  5 4 8 9 16 15 11 10 3 2 12 13 14 18 17 7 6 19 20 1 5
38:  5 4 8 9 16 15 14 13 12 11 10 3 2 1 20 19 18 17 7 6 5
39:  5 4 8 9 16 15 14 18 17 7 6 19 20 13 12 11 10 3 2 1 5
40:  5 4 8 9 16 17 7 6 19 18 14 15 11 10 3 2 12 13 20 1 5
41:  5 6 7 8 4 3 2 12 13 14 15 11 10 9 16 17 18 19 20 1 5
42:  5 6 7 8 4 3 10 9 16 17 18 19 20 13 14 15 11 12 2 1 5
43:  5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5
44:  5 6 7 8 9 16 17 18 19 20 1 2 12 13 14 15 11 10 3 4 5
45:  5 6 7 17 16 9 8 4 3 10 11 15 14 18 19 20 13 12 2 1 5
46:  5 6 7 17 16 15 11 10 9 8 4 3 2 12 13 14 18 19 20 1 5
47:  5 6 7 17 16 15 11 12 13 14 18 19 20 1 2 3 10 9 8 4 5
48:  5 6 7 17 16 15 14 18 19 20 13 12 11 10 9 8 4 3 2 1 5
49:  5 6 7 17 18 19 20 1 2 3 10 11 12 13 14 15 16 9 8 4 5
50:  5 6 7 17 18 19 20 13 14 15 16 9 8 4 3 10 11 12 2 1 5
51:  5 6 19 18 14 13 20 1 2 12 11 15 16 17 7 8 9 10 3 4 5
52:  5 6 19 18 14 15 11 10 9 16 17 7 8 4 3 2 12 13 20 1 5
53:  5 6 19 18 14 15 11 12 13 20 1 2 3 10 9 16 17 7 8 4 5
54:  5 6 19 18 14 15 16 17 7 8 9 10 11 12 13 20 1 2 3 4 5
55:  5 6 19 18 17 7 8 4 3 2 12 11 10 9 16 15 14 13 20 1 5
56:  5 6 19 18 17 7 8 9 16 15 14 13 20 1 2 12 11 10 3 4 5
57:  5 6 19 20 1 2 3 10 9 16 15 11 12 13 14 18 17 7 8 4 5
58:  5 6 19 20 1 2 12 13 14 18 17 7 8 9 16 15 11 10 3 4 5
59:  5 6 19 20 13 12 11 10 9 16 15 14 18 17 7 8 4 3 2 1 5
60:  5 6 19 20 13 14 18 17 7 8 4 3 10 9 16 15 11 12 2 1 5
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int Max = 111;
int map[Max][Max];
int vis[Max];
int way[Max];
int m,cas;
void dfs(int x,int len){
    for(int j=1;j<=3;j++){
        int u=map[x][j];
        if(u==m&&len==20)
        {
            cout<<cas<<":  "<<m<<" ";
            cas++;
            for(int k=1;k<20;k++)
            cout<<way[k]<<" ";
            cout<<m<<endl;
        }
        if(!vis[u]){
        vis[u]=1;
        way[len]=u;
        dfs(u,len+1);
        vis[u]=0;
        }
    }
}

int main(){
    for(int i=1;i<=20;i++){
        for(int j=1;j<=3;j++){
            cin>>map[i][j];
        }
    }
    while((cin>>m),m){
        cas=1;
        memset(vis,0,sizeof(vis));
        vis[m]=1;
        dfs(m,1);
    }
    return 0;
}

  

时间: 2024-12-29 12:03:55

基础深搜小结的相关文章

深搜基础题目 杭电 HDU 1241

HDU 1241 是深搜算法的入门题目,递归实现. 原题目传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1241 代码仅供参考,c++实现: #include <iostream> using namespace std; char land[150][150]; int p,q; void dfs(int x,int y){ land[x][y] = '*'; if(land[x-1][y]!= '@' && land[x+1]

深搜1--城堡问题

深搜1--城堡问题 一.心得 这个题目的栈实现可以看一看 也是很基础的迷宫问题,也就是一个深搜 二.题目及分析 三.代码及结果 递归 1 #include <iostream> 2 #include <stack> 3 #include <cstring> 4 using namespace std; 5 int R,C; //行列数 6 int rooms[60][60]; 7 int color[60][60]; //房间是否染色过的标记 8 int maxRoom

简单深搜:POJ1546——Sum it up

结束了三分搜索的旅程 我开始迈入深搜的大坑.. 首先是一道比较基础的深搜题目(还是很难理解好么) POJ 1564 SUM IT UP 大体上的思路无非是通过深搜来进行穷举.匹配 为了能更好地理解深搜 可以尝试去画一下二叉树理解一下,查看遍历的路径 代码还是百度到别人的自己再参悟- -佩服别人的功底啊 先上代码: /*POJ 1546 Sum it up*/ # include<iostream> # include<algorithm> # include<cstdio&g

NYOJ 迷宫寻宝(一)深搜

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=82 做这道题的时候迷迷糊糊的,,果然比较难..最后也是没有做出来..请教了一下学长,学长说我基础还不好..基础果然重要,这道题是一道搜索题,我没有考虑钥匙在门后面的情况,比如aBbSAG 多亏学长指教,通过这道题对深搜的理解又加深了一步~ #include <iostream> #include <cstdio> #include <cstring> using

算法学习笔记 二叉树和图遍历—深搜 DFS 与广搜 BFS

图的深搜与广搜 马上又要秋招了,赶紧复习下基础知识.这里复习下二叉树.图的深搜与广搜.从图的遍历说起,图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其经典应用走迷宫.N皇后.二叉树遍历等.遍历即按某种顺序访问"图"中所有的节点,顺序分为: 深度优先(优先往深处走),用的数据结构是栈, 主要是递归实现: 广度优先(优先走最近的),用的数据结构是队列,主要是迭代实现: 对于深搜,由于递归往往可以方便的利

广搜深搜二

<span style="color:#330099;">/* C - 广搜 基础 Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the

B广搜深搜

<span style="color:#330099;">/* B - 广搜/深搜 基础 Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u Submit Status Description There is a rectangular room, covered with square tiles. Each tile is colored either red or blac

BNU 1084 Expected Allowance (dp||母函数||深搜)

题目链接:http://www.bnuoj.com/v3/problem_show.php?pid=1084 题目大意:给你n个骰子,每个骰子有m个面,点数分别为(1-m),现在同时摇这n个骰子,(得到的点数和)-k  即为小明得到的钱数,当然小明每次最少会得到一元(即最后结果小于等于1时),问小明得到钱数的期望值. 解题思路:由于此题m*n较小,故按照普通的期望计算就行,即   摇到某个点数(i)的概率p*摇到的点数(i),其中显然(n=<  i  <=n*m)除以总的情况数(m的n次方)(

I深搜

<span style="color:#330099;">/* I - 深搜 基础 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit Status Description Given a specified total t and a list of n integers, find all distinct sums using numbers from the