题目描述
问题描述:
GeoSurvComp地质调查公司负责检测地下油藏。GeoSurvComp一次与一个大的矩形区域一起工作,并创建一个网格,将网格划分为多个方块。然后分别分析每个地块,使用传感设备确定该地块是否含有油。含油的情节被称为口袋。如果两个口袋相邻,则它们是同一个油藏的一部分。油藏可能相当大,可能含有大量的口袋。你的工作是确定网格中包含多少个不同的油藏。
Input:
输入文件包含一个或多个网格。每个网格以含有m和n的行开始,网格中的行和列的数量由一个空格分隔。如果m = 0,则表示输入结束; 否则1 <= m <= 100且1 <= n <= 100.之后是每行n个字符的m行(不包括行尾字符)。每个字符对应一个图,并且代表没有油的‘*’或代表油袋的‘@’。
Output:
对于每个电网,输出不同油量的数量。如果两个不同的口袋是水平,垂直或对角相邻的,则它们是同一个油藏的一部分。一个油藏不会超过100个口袋。
样例:
Sample Input
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
Sample Output
0
1
2
2
考察点:深搜+地图
易错点:忘记将已经搜过的口袋设置为普通地 (@变成*)或者是吃掉了换行。
解题思路:
明确是深搜问题然后写出判断方向后继续搜索。存入地图找到深搜的开始点,开始搜索。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int r,c;
int fx[9]={0,0,1,-1,-1,-1,1,1},fy[9]={1,-1,0,0,-1,1,-1,1};
char mapp[105][105];
int s;
void dfs(int x,int y){
mapp[x][y]='*';//把等于@的都变成*,因为它们属于同一油桶
for(int i=0;i<8;i++){
int a=x+fx[i];
int b=y+fy[i];
if(a>0&&a<=r&&b>0&&b<=c&&mapp[a][b]=='@'){
dfs(a,b);
}
}
}
int main(int argc, char** argv) {
while(cin>>r>>c&&r!=0){
s=0;
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
cin>>mapp[i][j];
}
}
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
if(mapp[i][j]=='@'){
dfs(i,j);
s++;
}
}
}
cout<<s<<endl;
}
return 0;
}
//用scanf输入含字符,整型多样例
cin与scanf的区别请参考: C++中cin和scanf的区别(总结)!!!
while(scanf("%d%d",&r,&c)&&r!=0){
s=0;
getchar();//吸收回车
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
scanf("%c",&mapp[i][j]);
}
getchar();//吸收回车
}