入门深度搜索问题--dfs(水题)
问题描述:
自从离开ACM基地后,小陈迷上了区块链,疯狂阅读有关区块链的资讯。这不,他发现有一个 N × M 大小的城市--米花市,这个城市分散着零零落落的区块,当区块的相邻任意八个方向(上、下、左、右、
左上、左下、右上、右下)有一个区块时,则称这两个区块是相连的,且这两个区块同属一个区块链。请你求出最大的区块链有多少个区块(只有一个区块也可称为区块链)。其中 . 代表空地, * 代表区块。
input:
每组数据第一行输入 N(1 <= N <= 100) 和 M(1 <= M <= 100),分别代表城市的行数和列数。
接下来 2 ... N + 1 行,每行 M 个字符。
output:
结果为一行,即输出最大区块链的区块数。
sample input:
3 8
..***...
...*.*..
**......
5 6
.*.*.*
*.*.*.
..*...
....**
****..
sample output:
5
7
Hint:
3 8
..***...
...*.*..
**......
在这个3X8的图中,含有*且符合要求的区块链有2个,其中最大的为5个,所以输出结果是5
AC code:
#include<iostream>
#include<cstdio>
using namespace std;
char A[105][105];
int ans=0;
bool flag[100][100];
int num1,num2;
void dfs(int x,int y)
{
if(x>=num1||y>=num2||A[x][y]=='.') //如果数组越界或者是遇到'.'的,都跳出dfs递归
{
return ;
}
if(A[x][y]=='*'&&flag[x][y]==true) //如果是'*',并且没有被执行过的话,那么就走一走
{
flag[x][y]=false; //这里吧flag数组对应的值设为false,后面不用再把它变回true,因为这道题的通路是相互连通的,这里想不明白的话好好想想,与之前写的博客的棋盘问题区分开
ans++;
//printf("x=%d,y=%d,cnt=%d\n",x,y,cnt);
dfs(x+1,y+1); //这里应该很好理解,就是向八个方向递归
dfs(x+1,y-1);
dfs(x-1,y+1);
dfs(x-1,y-1);
dfs(x+1,y);
dfs(x-1,y);
dfs(x,y+1);
dfs(x,y-1);
}
}
int main()
{
while(scanf("%d %d",&num1,&num2)!=EOF)
{
ans=0;
int Max=0;
for(int i=0;i<num1;i++)
{
for(int j=0;j<num2;j++)
{
cin>>A[i][j];
flag[i][j]=true;
}
}
for(int i=0;i<num1;i++)
{
for(int j=0;j<num2;j++)
{
if(A[i][j]=='*')
{
dfs(i,j); //从有*的地方开始深搜;
if(ans>Max) // 深搜完了之后,取最大的值记录在Max中,就相当与取最优的解;
{
Max=ans;
}
ans=0; //因为ans定义的是全局变量,所以每次做完之后都要重置为0,下一次重新开始计数;
}
}
}
cout<<Max<<endl;
}
return 0;
}
TIP:关于代码,题目中的注释想必已经写的很清楚了,还有不明白的就所看几遍吧
posted on 2018-04-03 11:25 superhero11 阅读(504) 评论(0) 编辑 收藏 举报