CSU-ACM2016暑期集训训练4-BFS(F - Oil Deposits)
F - Oil Deposits
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description
GeoSurvComp地质调查公司负责探测地下石油储藏。 GeoSurvComp现在在一块矩形区域探测石油,并把这个大区域分成了很多小块。他们通过专业设备,来分析每个小块中是否蕴藏石油。如果这些蕴藏石油的小方格相邻,那么他们被认为是同一油藏的一部分。在这块矩形区域,可能有很多油藏。你的任务是确定有多少不同的油藏。
Input
输入可能有多个矩形区域(即可能有多组测试)。每个矩形区域的起始行包含m和n,表示行和列的数量,1<=n,m<=100,如果m =0表示输入的结束,接下来是n行,每行m个字符。每个字符对应一个小方格,并且要么是'*',代表没有油,要么是'@',表示有油。
Output
对于每一个矩形区域,输出油藏的数量。两个小方格是相邻的,当且仅当他们水平或者垂直或者对角线相邻(即8个方向)。
Sample Input
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
Sample Output
0
1
2
2
解题思路:题目比较短小,容易理解。可以采用广度优先。广度优先采用的典型数据结构是优先队列。这里采用结构体记录位置。
首先从一个@出发,将此位置标记为已访问,并将所有能到达的位置标记为已访问(上下左右及对角线(8个位置),而且存在石油),并且加入队列中,当队列不为空时重复以上操作。为空后,继续枚举未访问而有石油的位置,调用BFS()。由此可见,石油的块数即为调用BFS()的次数。
注意:使用队列时要注意清空(这里while循环中没有其余的跳出循环语句,可以不用清空)。
每一组数据测试之前对标记数组清零。
memset()--之前都是一直用memset来清空一维数组
void *memset(void *s, int ch, size_t n);
函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
二维数组也适用:如memset(vis,0,sizeof(vis));/memset(&vis[0][0],0,sizeof(vis))。第一个参数为要操作数据的首地址。
收获感想:对BFS更加理解,之前队列用得也很少,通过做题,知道队列理解也不是那么困难。
#include<iostream> #include<stdio.h> #include<queue> #include<cstring> using namespace std; int vis[101][101],n,m; char Map[101][101]; struct node { int x,y; }; queue<node> q; bool jd(int a,int b) { if(a>=0&&a<n&&b>=0&&b<m&&Map[a][b]=='@') return true; else return false; } void BFS(node n){ while(!q.empty())q.pop();//初始化队列Q; q.push(n);//可用结构体,也可以哈希一下 while(!q.empty()) {//当q不为空 node temp=q.front();//取出队首元素u; q.pop(); int cx,cy; cx=temp.x; cy=temp.y; if(jd(cx+1,cy)&&vis[cx+1][cy]==0) {//此区域合法且有油 vis[cx+1][cy]=1;//入队;访问标记; temp.x=cx+1; temp.y=cy; q.push(temp); } if(jd(cx+1,cy+1)&&vis[cx+1][cy+1]==0) { vis[cx+1][cy+1]=1; temp.x=cx+1; temp.y=cy+1; q.push(temp); } if(jd(cx,cy+1)&&vis[cx][cy+1]==0) { vis[cx][cy+1]=1; temp.x=cx; temp.y=cy+1; q.push(temp); } if(jd(cx-1,cy+1)&&vis[cx-1][cy+1]==0) { vis[cx-1][cy+1]=1; temp.x=cx-1; temp.y=cy+1; q.push(temp); } if(jd(cx-1,cy)&&vis[cx-1][cy]==0) { vis[cx-1][cy]=1; temp.x=cx-1; temp.y=cy; q.push(temp); } if(jd(cx-1,cy-1)&&vis[cx-1][cy-1]==0) { vis[cx-1][cy-1]=1; temp.x=cx-1; temp.y=cy-1; q.push(temp); } if(jd(cx,cy-1)&&vis[cx][cy-1]==0) { vis[cx][cy-1]=1; temp.x=cx; temp.y=cy-1; q.push(temp); } if(jd(cx+1,cy-1)&&vis[cx+1][cy-1]==0) { vis[cx+1][cy-1]=1; temp.x=cx+1; temp.y=cy-1; q.push(temp); } } } int main(){ while(cin>>n>>m) { if(n==0&&m==0) return 0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>Map[i][j]; memset(vis,0,sizeof(vis)); int ans=0; node tp; for(int i=0;i<n;i++) for(int j=0;j<m;j++) { if(Map[i][j]=='@'&&vis[i][j]==0) { tp.x=i;tp.y=j; BFS(tp); ans++; } } printf("%d\n",ans); } return 0; }

浙公网安备 33010602011771号