1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
0 1 2 2
首先知道油田的整体面积可以8个方向进行遍历,所以创建两个数组x,y进行坐标的获得。
int dx[8]={-1, -1, 0, 1, 1, 1, 0, -1};//上-右上-右-右下-下-左下-左-左上
int dy[8]={ 0, 1, 1, 1, 0,-1,-1, -1};
BFS里面用二维数组进行遍历
for(int i=1;i<=M;i++)
for(int j=1;j<=N;j++)
if(map[i][j]=='@'&&!visited[i][j])
find_oil(i,j);
若是油田就进入find_oil,用队列来实现,head=0,tail=1,
struct queue{
int xx;int yy;
}que[10100];
(1)未标记过的话,就进行广度优先遍历,
while(head<tail)是一个大的循环,
(a)
for(int i=0;i<8;i++)
{x1=x+dx[i];y1=y+dy[i];//八个方向
if(x1>=1&&x1<=M&&y1>=1&&y1<=N)//判断是否越界
以上都满足并且是油田且未遍历过,就进入队列,并标记走过
(b)以上不满足的话,则直接head++,直到head>tail
(2)若标记过,直接对油田标记走过,并返回。
用一个visited数组来标记走过的油田。
#include<iostream>
#include<cstring>
using namespace std;
int M,N,total;
char map[110][110];
int visited[110][110];
int dx[8]={-1, -1, 0, 1, 1, 1, 0, -1};//上-右上-右-右下-下-左下-左-左上
int dy[8]={ 0, 1, 1, 1, 0,-1,-1, -1};
struct queue{
int xx;int yy;
}que[10100];
void find_oil(int x,int y)
{
int x1,y1;
int head,tail;
if(!visited[x][y])
{
total++;//第一次遍历 则加1 地图标记遍历过了
visited[x][y]=1;
}
if(visited[x][y]==1)//已经标记过,找周围的油田
{
head=0,tail=1;
que[0].xx=x; // 注意刚才用的是 que[head].xx=x;
que[0].yy=y; //但是下面的循环会让head的值并非是0,所以
while(tail>head)
{
x=que[head].xx;
y=que[head].yy;
for(int i=0;i<8;i++)
{
x1=x+dx[i];y1=y+dy[i];//八个方向
if(x1>=1&&x1<=M&&y1>=1&&y1<=N)//判断是否越界
if(map[x1][y1]=='@'&&!visited[x1][y1])
{
que[tail].xx=x1;
que[tail].yy=y1;
visited[x1][y1]=1;
tail+=1;
}
}
head++;
}
}
}
void BFS()
{
for(int i=1;i<=M;i++)
for(int j=1;j<=N;j++)
if(map[i][j]=='@'&&!visited[i][j])
find_oil(i,j);
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>M>>N)
{
cin.get();
if(M<=0||N<=0) break;
total=0;
memset(map,0,sizeof(map));
memset(visited,0,sizeof(visited));//地图标记清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++)
cout<<map[i][j];
cout<<endl;
}*/
BFS();
cout<<total<<endl;
}
return 0;
}