小学生玩ACM----广搜
Oil Deposits
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7955 Accepted Submission(s): 4678
#include <iostream>
#include <queue>
using namespace std;
int n,m,visit[111][111],xx[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}}; //visit是用来标记已经访问过了的点,xx数组是用来记录方向的,到时候就只要直接加就好了
char map[111][111];
struct ssss
{
int x,y; //因为要存的是坐标,没有可以装两个变量的队列,所以先放结构体打包再加入队列
}ss;
queue<ssss> q,qq; //结构体类型的队列,q是要用到,qq是用来初始化q的
void bfs()
{
while(!q.empty())
{
ss=q.front();q.pop(); //用ss取出队首元素并删除它
int X=ss.x,Y=ss.y;
map[X][Y]='*';visit[X][Y]=0; //在map里面把当前坐标从@变成×,visit标记为已经访问
for(int i=0;i<8;i++)
{
int x=X+xx[i][0]; //8个方向一个一个来,嘿嘿
int y=Y+xx[i][1];
if(x>=0&&x<n&&y>=0&&y<m) //判断是否在范围内
if(visit[x][y]&&map[x][y]=='@') //判断是否访问过和是否为油田@
{
visit[x][y]=0; //标记已经访问
ss.x=x,ss.y=y;q.push(ss); //先打包,再入队
}
}
}
}
int main (void)
{
int i,j,k,l,s;
while(cin>>n>>m&&(n||m))
{
for(i=0;i<n;i++)
for(j=0;j<m;j++)
cin>>map[i][j],visit[i][j]=1;
q=qq;
for(i=s=0;i<n;i++) //全图搜索
for(j=0;j<m;j++)
if(map[i][j]=='@') //当找到油田@
s++,ss.x=i,ss.y=j,q.push(ss),bfs(); //油田群数量加一,打包,入队,同时进行广搜,就是把它周围连着的油田全部找出来,因为这一群只能算一个油田嘛
cout<<s<<endl;
}
return 0;
}