[原题链接](http://acm.hdu.edu.cn/showproblem.php?pid=1241)
题目描述很重要
思路:1.使用搜索。
2.假如能从一个油田搜到另一个油田,则说明这两个油田是相连的,所以独立油田数-1。
注意:1.这个题是8个方向
2.在搜索时所有@都被标记,因为中间有 * 隔开大油田,所以搜索时是从* 处搜索的(看下面代码 *** Ⅰ *** 处)。
写法一:
#include<iostream>
#include<cstring>
using namespace std;
int dir[8][2]={{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};//8个方向
char Map[105][105];//存放地图
bool vis[105][105];//存放标记
int m,n;
int res;
bool DFS(int x,int y){
if(Map[x][y]=='*' || vis[x][y])
return false;
vis[x][y]=true;
//对8个方向进行搜索
for(int i=0;i<8;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
//必须在边界内
//假如从某一个 @能搜到另一个 @ 则说明它们两个相连,是一个大油田
//这时 独立油田数 res--
if( tx>=0 && tx<m && ty>=0 && ty<n )
if(DFS(tx,ty))
res--;
}
return true;
}
int main(){
while( cin>>m>>n && n+m ){
res=0;
memset(vis,false,sizeof(vis));
for(int i=0;i<m;i++)
for(int j=0;j<n;j++){
cin>>Map[i][j];
if(Map[i][j]=='@')
res++;
}
//******** Ⅰ ********
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
if(!vis[i][j])
DFS(i,j);
cout<<res<<endl;
}
}
写法二:
与一没有什么本质区别,可以拓展一下思路
#include<cstdio>
#include<cstring>
using namespace std;
char Map[110][110];
int vis[110][110];
int n,m,cnt;
void dfs(int x,int y,int id){
if(x<0 || x>=m || y<0 || y>=n) return; //超出边界
if(vis[x][y] || Map[x][y]!='@') return; //如果走过且不是油田
vis[x][y]=id; //连通分量编号
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
if(dx==0 && dy==0) continue;
else dfs(x+dx,y+dy,id);
}
}
}
int main(){
while(scanf("%d%d",&m,&n)!=EOF && n+m){
cnt=0;
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++)
scanf("%s",&Map[i]);
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
if(Map[i][j]=='@' && !vis[i][j])
dfs(i,j,++cnt);
printf("%d\n",cnt);
/* for(int i=0;i<m;i++){
for(int j=0;j<n;j++)
printf("%d ",vis[i][j]);
printf("\n");
}*/
}
return 0;
}