徐老师的城市魅力

题目描述

徐老师所在的城市可以看做一个 N M 的地图,在这个城市中每个格点都是一个建筑,每

个建筑有它自己的美丽值,城市的外围都是空地,我们认为空地的美丽值为 0

若一个建筑的上下左右四个建筑中有和它美丽值相同的建筑,则认为这两个建筑同属于一个公

司(一个公司可以只有一个建筑)。

徐老师作为这个城市的城市规划研究员,他有一个看法:

1. 如果有一个公司的美丽值比它周围其他所有的建筑的美丽值都低,那就认为这个公司是

不美丽的。

2. 如果有一个公司的美丽值比它周围其他所有的建筑的美丽值都高,那就认为这个公司是

美丽的。

3. 若不满足以上情况的公司则认为是一个颜值一般的公司

现在徐老师拿到了城市的地图,他想要知道这个城市中有多少个不美丽公司和多少个美丽公

司。

输入格式

输入第一行包含两个自然数 N M,表示有一个 N M的地图

接下来 N 行每行包含 M 个数字,每个数字表示一个建筑的美丽值 bi,j

输出格式

输出一行包含两个整数,分别表示不美丽公司的数量和美丽公司的数量

数据范围

对于 20% 的数据中,N, M ≤ 10对于 60% 的数据中,N, M ≤ 100

对于 100% 的数据中,N, M ≤ 1000; bi,j <= 1000000000

样例输入

3 4

1 3 2 6

1 2 2 7

3 2 2 5

样例输出

1 3

样例解释

唯一的不美丽公司的美丽值为 1 ,而美丽公司有 3 个,分别是美丽值为 3 的两个公司和美丽值

为 7 的公司

限制
1000ms
512 MB

思路:这道题其实是连通块那道题的举一反三。这道题深搜广搜都可以做。不过深搜有点容易超时,所以在下文中我是用光搜来做的。如果不知道连通块那道题怎么做的话可以去看​​​​​​经典搜索算法——广度优先搜索【数水坑(深搜/广搜连通块)】_愿与君同赏月的博客-CSDN博客​​​​​​​

所以,这道题应该这么做

1.读入数据

2.遍历行,列,只要在该点上没有被遍历过,就从该点开始操作

3.先把该初始化的初始化,再bfs,最后判断如果该点周围的最小美丽值>该公司的美丽值,则说明该公司是不美丽的,如果周围的最大美丽值<该公司的美丽值,说明该公司是美丽的,做相应操作

程序=数据结构+算法——王恩全

广搜的具体操作请看C++ 广搜_熬夜的Alan Walker的博客-CSDN博客_c++ 广搜 或C/C++ 之 广度优先搜索_MWYA的博客-CSDN博客_c++ 广度优先搜索

那么这道题具体代码如下:

#include <bits/stdc++.h>
using namespace std;
int dx[5]= {0,0,1,-1},dy[5] = {1,-1,0,0},a[10001][1001],vis[10001][1001],n,l,m,maxn,minn,k;
queue<int>x,y;
void bfs(int xx,int yy)
{
  x.push(xx),y.push(yy);
  while(!x.empty())
  {
    int xxx = x.front(),yyy = y.front();
    x.pop(),y.pop();
    for(int i = 0; i < 4; i++)
      if(xxx + dx[i] > 0 && xxx + dx[i] <= n && yyy + dy[i] > 0 && yyy + dy[i] <= k)//继续广搜十分合法的判断条件
        if(a[xxx + dx[i]][yyy + dy[i]] == a[xx][yy])
        {
          if(!vis[xxx + dx[i]][yyy + dy[i]])
          {
            vis[xxx + dx[i]][yyy + dy[i]] = 1;
            x.push(xxx + dx[i]);
            y.push(yyy + dy[i]);
          }
        }
        else
        {
          minn = min(minn,a[xxx + dx[i]][yyy + dy[i]]);
          maxn = max(maxn,a[xxx + dx[i]][yyy + dy[i]]);
        }
  }
}
int main()
{
  cin>>n>>k;
  for(int i = 1; i <= n; i++)
    for(int j = 1; j <= k; j++)
      cin>>a[i][j];//读入数据
  for(int i = 1; i <= n; i++)
    for(int j = 1; j <= k; j++)
      if(vis[i][j] != 1)//如果没被遍历过
      {
        minn = 12311215;
        maxn = -12311215;
        vis[i][j] = 1;//初始化
        bfs(i,j);//广搜
        if(minn > a[i][j] && minn != 12311215) l++;//不美丽公司的数量+1
        if(maxn < a[i][j] && maxn != -12311215) m++;//美丽公司的数量+1
      }
  cout<<l<<" "<<m;
  return 0;
}

祝大家阅读愉快! 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值