今天,我们主要讲一下搜索(dfs)。
它和贪心、动态规划一样,都是一种算法。它主要运用到了函数,通过每一个分支来搜索全局,来达到目的(太暴力了)。
它主要核心思想是:通过一个主支,分成多个分支,直到每个分支都走到尽头。这样就能把全局都搜索一遍。(也就是函数里边套函数,跟递归很像)
dfs主要用到的函数都是void类型的,因为它搜索完后就无了,不用返回值,所以是不用返回值的void。
话不多说,直接来做题!!!
【题目描述】
有一间长方形的房子,地上铺了白色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
【输入】
包括多组数据。每组数据的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下:
‘.’:黑色的瓷砖;
‘#’:白色的瓷砖;
‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每组数据中唯一出现一次。
当在一行中读入的是两个零时,表示输入结束。
【输出】
对每组数据,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。
【输入样例】
6 9
. . . . # .
. . . . . #
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
# @. . . #
. # . . # .
0 0
(抱歉,有些不规范,尽力了)
【输出样例】
45
好了,先分析题目。我们可以向相邻的黑色瓷砖移动,相邻是上下左右,不能斜着,注意!计算我们能到达多少个黑色瓷砖(要包括起始的黑瓷砖哦!)。输入0 0为结束。
. 是黑色的瓷砖;#是白色的瓷砖;@是初始的瓷砖。要输入h行,w列。
有的同学可能以为0 0没有什么用处,不!如果输入的是多组数据呢?这时候就要有终止程序的东东了。
分析完了,接下来先定义四个变量(w和h记录“地图大小”,sx和sy记录初始位置)和一个二维数组(它的“地图”),我建议都开到全局,不开到全局有可能是随机数值。
接下来,输入w,h。然后二维数组输入(外层为h,内层为w)。接下来,我们的void函数就要登场了!
我们前面也说了搜索的主要思想,有主支也有分支。在这里,主支就是起始位置——@;分支就是每次我们能走的四个位置,这就是分支!
定义两个参数,x和y。大家想象一个坐标系:x+1,y+0是向右;x+(-1),y+0是向左;x+0,y+1是向上;x+0,y+(-1)是向下;这就是四个方向。
所以我们要向这四个方向走,就要用函数来用。
dfs(x+1,y+0)......
我教你们一个方法,可以定一个二维数组
xy[4][2]={{1,0},{-1,0},{0,1},{0,-1}}
这样来一个for循环重复四次:
int xx=x+[i][0],yy=y+[i][1];
dfs[xx][yy];
这样就不用写四遍函数了!
好了,继续讲题。
我们向四个方向走要满足以下条件:
1.不越界
2.不要走到白色的瓷砖
3.不要走重复的路(否则你走的总砖数就会增多)
为什么要满足我就不说了,相信大家都知道。
这样搞个判断,就行了。
重复的路其实再定义一个二维数组就行了,每走过一段路就把这个标记的二维数组给更改一下,具体我就不说了。
这样就判断完了。
如果都满足使总共的砖数+1,dfs(xx,yy)。
最后函数运行完之后肯定是无路可走,否则程序会继续运行,这时候输出总砖数就行了。
运行完一组数据把标记二维数组,总砖数什么的都给清零。二维数组清零用memset(数组名,0,sizeof(数组名)),头文件是cstring。这个自己查,我不说了。
对了,输入w,h的时候记得判断是否都为零。如果是的话直接return 0;否则就没事了。
思路我来说,代码交给你们!
好了,今天就讲到这里吧!你们学废了吗?