- 【问题描述】
贝茜像其它奶牛一样正在吃草,她注意到她得到的是一个平于海平面的牧场。海拔 只有1 米或者更高的草不那么美味。沿着这些劣草继续咀嚼,她意识到,这没有食欲的食物长成两侧的丘陵,形成了青翠美味丰富草地海洋中的一系列劣质 草小岛 。贝茜穿上她的实验服,决心测定她的牧场有多少劣草小岛。她画出一张画有被分成 R (1 < R <= 1,000) 行、C (1 < C<= 1,000)列的 1*1 小格子的地图。她为每个小格子测量了海拔高 度,并四舍五入到非负整数。她饥饿地把所有美味草标的海拔标记成 0。 她着手统计小岛。任何水平、垂直、斜向相邻的两个有劣草的格子将被认为在同一个岛中。在每 一张她提供的地图中有多少劣草岛屿呢?
- 【输入格式】
第 1 行: 两个用空格隔开的整数: R 和 C ,接下来的 R 行,每行是C 个由空格隔开的整数,分别表示地图中的 一行。
- 【输出格式】
一个代表岛屿数的整数。
- 【输入样例】
8 7
4 3 2 2 1 0 1
3 3 3 2 1 0 1
2 2 2 2 1 0 0
2 1 1 1 1 0 0
1 1 0 0 0 1 0
0 0 0 1 1 1 0
0 1 2 2 1 1 0
0 1 1 1 2 1 0
- 【输出样例】
2
- 【数据范围】
1 < R <= 1,000 1 < C<= 1,000
- 【思路梳理】
题目有些难懂,但是不难能够得知是要求整个地图中劣草岛屿的个数。显然每一个劣草岛屿都是一个八连块,因此不难得知我们是要求出八连块的总数,使用Floodfill,种子填充算法即可。因为当草的海拔高度大于等于1m时,草就不再美味,所以说判断八连块的条件是该格子的数值不为0.代码给出如下。
•【Cpp代码】
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#define maxn 1005
using namespace std;
int r,c,map[maxn][maxn],belong[maxn][maxn],ans=0;
struct loca
{
int x,y;
};
bool vis[maxn][maxn];//vis数组其实是可以被belong和map这两个数组所代替的
int dx[]={0,1,1,1,0,-1,-1,-1};//东 东南 南 西南 西 西北 北 东北
int dy[]={1,1,0,-1,-1,-1,0,1};
void BFS(int x,int y,int cnt)//用cnt标记结点(x,y)属于哪一个八连块
{
queue<loca>q;
q.push((loca){x,y});
vis[x][y]=true;
belong[x][y]=cnt;
while(!q.empty())
{
x=q.front().x,y=q.front().y;q.pop();
for(int i=0;i<8;i++)//八个方向而非是四个
{
int xx=x+dx[i],yy=y+dy[i];
if(vis[xx][yy]) continue;
if(xx<1 || xx>r || yy<1 || yy>c) continue;
if(map[xx][yy]==0) continue;//当(x,y)的高度大于等于1m时,我们就判定这是一个劣草格子
q.push((loca){xx,yy});
vis[xx][yy]=true;
belong[xx][yy]=cnt;
}
}
}
int main()
{
freopen("badgras.in","r",stdin);
freopen("badgras.out","w",stdout);
cin>>r>>c;
memset(map,0,sizeof(map));
memset(belong,0,sizeof(belong));
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++) scanf("%d",&map[i][j]);
memset(vis,0,sizeof(vis));
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)if(!vis[i][j] && map[i][j]!=0 && belong[i][j]==0)
BFS(i,j,++ans);//每找到一个八连块,ans自增1
/*for(int i=0;i<=r;i++)
{for(int j=0;j<=c;j++) printf("%d ",belong[i][j]);
cout<<endl;
}*/
cout<<ans;
return 0;
}