一千题,No.0020(山)

Drizzle 前往山地统计大山的数目,现在收到这片区域的地图,地图中用0(平地)1(山峰)绘制而成,请你帮忙计算其中的大山数目
山总是被平地四面包围着,每一座山只能在水平或垂直方向上连接相邻的山峰而形成。一座山峰四面被平地包围,这个山峰也算一个大山
另外,你可以假设地图的四面都被平地包围着。

要求:

输入:第一行输入M,N分别表示地图的行列,接下来M行每行输入N个数字表示地图
输出:输出一个整数表示大山的数目

示例:

输入:

4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

输出:

3

 解题思路:

BFS:

1,循环处理,当节点未走过时res++;

2,每次res++时BFS一次将同个岛屿都设置为走过

3,输出res;

经过oj发现数组长度最小设置为2002才可以通过

c++代码如下:

#include <bits/stdc++.h>

using namespace std;

int arrA[2002][2002];
int arrB[2002][2002];
deque<pair<int,int>> d;
int res = 0;

void BFS(int x,int y)
{
    while(!d.empty())
    {
        x = d.begin()->first;
        y = d.begin()->second;

        //右
        if(arrA[x][y+1] == 1 && arrB[x][y+1] == 0)
        {
            d.push_back({x,y+1});
            arrB[x][y+1] = 1;
        }
        //下
        if(arrA[x+1][y] == 1 && arrB[x+1][y] == 0)
        {
            d.push_back({x+1,y});
            arrB[x+1][y] = 1;
        }
        //左
        if(arrA[x][y-1] == 1 && arrB[x][y-1] == 0)
        {
            d.push_back({x,y-1});
            arrB[x][y-1] = 1;
        }
        //上
        if(arrA[x-1][y] == 1 && arrB[x-1][y] == 0)
        {
            d.push_back({x-1,y});
            arrB[x-1][y] = 1;
        }

        d.erase(d.begin());
    }
}

int main()
{
    int x,y;
    cin >> x >> y;
    ::memset(arrA,0,sizeof(arrA));
    ::memset(arrB,0,sizeof(arrB));

    for(int i = 1;i <= x;++i)
    {
        for(int j = 1;j <= y;++j)
        {
            cin >> arrA[i][j];
        }
    }

    for(int i = 1;i <= x;++i)
    {
        for(int j = 1;j <= y;++j)
        {
            if(arrB[i][j] == 0 && arrA[i][j] == 1)
            {
                ++res;
                d.push_back({i,j});
                arrB[i][j] = 1;
                BFS(i,j);
            }
        }
    }

    cout << res;
}
/*
10 10
1 1 0 1 1 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0
 */

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值