Cpp环境【Usaco 2008】劣草岛屿

本文介绍了一道Usaco算法竞赛题目,要求计算一个牧场中劣草岛屿的数量。岛屿由海拔大于等于1米的草格子组成,且相邻的劣草格子被视为同一岛屿。通过Floodfill算法,可以有效地找出所有劣草岛屿。样例输入和输出展示了算法的应用,代码使用C++实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 【问题描述】

贝茜像其它奶牛一样正在吃草,她注意到她得到的是一个平于海平面的牧场。海拔 只有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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值