《算法竞赛·快冲300题》每日一题:“造电梯”

news2025/4/17 15:38:46

算法竞赛·快冲300题》将于2024年出版,是《算法竞赛》的辅助练习册。
所有题目放在自建的OJ New Online Judge。
用C/C++、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。

文章目录

  • 题目描述
  • 题解
  • C++代码
  • Java代码
  • Python代码

造电梯” ,链接: http://oj.ecustacm.cn/problem.php?id=1790

题目描述

【题目描述】 现在给你一张建筑的平面图,按照要求,建筑的每一个部分都应该是轮椅使用者可以到达的,这意味着必须安装电梯。
   给定的平面图是一个n*m的矩阵,里面的数字表示这个位置的高度。可以在建筑中的任意位置放置电梯,电梯可以停在所有楼层。
   需要保证可以使用电梯到达所有高楼层。相同高度的楼层之间是互通的,联通准则是四联通。
   需要求解最少需要多少个电梯,注意高度为1的不需要电梯。
   下图展示了样例2的可视化三维图。
在这里插入图片描述

【输入格式】 输入第一行为n和m(1≤n,m≤500)。
   接下来n行,每行m个整数xij,表示平面图,0≤xij≤10^9。
【输出格式】 输出最少电梯数量
【输入样例】

样例12 3
1 2 3
1 3 2

样例26 7
0 0 0 0 0 0 0
0 1 2 3 2 1 0
0 1 2 3 2 1 0
0 0 0 0 0 0 0
0 1 0 5 0 0 0
0 0 0 0 0 0 0

【输出样例】

样例12

样例22

题解

   电梯是装在建筑内部的,例如样例2,高度5的柱子内部需要一个电梯,楼梯状的建筑也需要一个电梯。
   注意一个建筑内部可能需要不止一个电梯,例如平面上一个建筑的高度是{5, 2, 4},那么需要在5和4上建2个电梯。
   本题是“洪水填充(《算法竞赛》清华大学出版社,罗勇军,郭卫斌著,120页,3.3 洪水填充)”的应用:从最高处开始倒水,那么水会平流或者往下流,这相当于建了一部电梯;这次倒水没有流到的地方,继续从下一个最高处倒水…
   以样例2为例:
   (1)从最高的“5”开始倒水,水会平流或往下流,那么会继续淹没所有的“0”。这次倒水相当于建设了一部电梯。没有被这次倒水淹没的有第二行和第三行的“1 2 3 2 1”,还有倒数第二行的“1”。
   (2)继续从剩下的最高点“3”开始倒水,水会平流或往下流,那么第二行和第三行的“1 2 3 2 1”,还有所有的“0”都会淹没。这次倒水也相当于建设了一部电梯。没有被这次倒水淹没的有倒数第二行的“1”,不过它不需要建设电梯。
   “洪水填充”用BFS或DFS都行,下面的代码用BFS实现。把平面的所有点放进优先队列,然后依次取出队列中的最高点,并从它开始“洪水填充”。
【重点】 洪水填充。

C++代码

   代码的计算复杂度,设平面上共n个点,每个点只需要处理一次,优先队列进出一次是O(logn)的,所以总复杂度O(nlogn)。

#include <bits/stdc++.h>
using namespace std;
int dx[4] = { 1, 0, -1, 0 };  //上下左右
int dy[4] = { 0, 1, 0, -1 };
struct Point {
    int x, y, h;                     //坐标xy、高度h
    Point(int x_, int y_, int h_) { x = x_; y = y_; h = h_; };
    bool operator<(const Point& r) const { return (h < r.h); }
};
int n, m;
int a[505][505];
bool done[505][505];  //done[x][y]=1表示(x,y)已经淹没
void floodfill(int x, int y) {      //“洪水填充”,平流或往下流
    done[x][y] = true;              //标记为淹没
    for (int i = 0; i < 4; i++) {    //扩散周围与它等高或矮的点
        int nx = x + dx[i], ny = y + dy[i];
        if (nx < 0 || nx >= m || ny < 0 || ny >= n || done[nx][ny]) continue;
        if (a[nx][ny] <= a[x][y])
            floodfill(nx, ny);   //继续“洪水填充”
    }
}
int main() {
    cin >> n >> m;
    priority_queue<Point> Q;   //优先队列,队首的h最大
    for (int j = 0; j < n; j++)
        for (int i = 0; i < m; i++) {
            cin >> a[i][j];
            done[i][j] = (a[i][j] <= 1);        //0和1标记为已经淹没
            if(a[i][j] > 1)
                Q.push(Point(i, j, a[i][j]));   //把点放进优先队列
        }
    int ans = 0;
    while (!Q.empty()) {
        Point p = Q.top();      //每次取出剩下的最高点
        Q.pop();
        if (!done[p.x][p.y]) {  //如果它没有淹没过,就“洪水填充”
            ans++;              //这次倒水相当于建设了一部电梯
            floodfill(p.x, p.y); //“洪水填充”
        }
    }
    cout << ans << endl;
    return 0;
}

Java代码

import java.util.*;
class Point implements Comparable<Point> {
    int x, y, h;
    public Point(int x_, int y_, int h_) {
        x = x_;
        y = y_;
        h = h_;
    }
    public int compareTo(Point r) { return Integer.compare(-h, -r.h);  }
}

public class Main {
    static int[] dx = { 1, 0, -1, 0 };
    static int[] dy = { 0, 1, 0, -1 };
    static int n, m;
    static int[][] a;
    static boolean[][] done;
    public static void floodfill(int x, int y) {
        done[x][y] = true;
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if (nx < 0 || nx >= m || ny < 0 || ny >= n || done[nx][ny])
                continue;
            if (a[nx][ny] <= a[x][y])
                floodfill(nx, ny);
        }
    }
    public static void floodfill_bfs(int sx, int sy) {
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[] { sx, sy });
        done[sx][sy] = true;
        while (!queue.isEmpty()) {
            int[] curr = queue.poll();
            int x = curr[0];
            int y = curr[1];
            for (int i = 0; i < 4; i++) {
                int nx = x + dx[i], ny = y + dy[i];
                if (nx >= 0 && nx < m && ny >= 0 && ny < n && !done[nx][ny] && a[nx][ny] <= a[x][y]) {
                    queue.add(new int[] { nx, ny });
                    done[nx][ny] = true;
                }
            }
        }
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        n = input.nextInt();
        m = input.nextInt();
        a = new int[m][n];
        done = new boolean[m][n];
        PriorityQueue<Point> Q = new PriorityQueue<>();
        for (int j = 0; j < n; j++) {
            for (int i = 0; i < m; i++) {
                a[i][j] = input.nextInt();
                done[i][j] = (a[i][j] <= 1);
                if (a[i][j] > 1)    Q.add(new Point(i, j, a[i][j]));
            }
        }
        int ans = 0;
        while (!Q.isEmpty()) {
            Point p = Q.poll();
            if (!done[p.x][p.y]) {
                ans++;
                floodfill_bfs(p.x, p.y);
            }
        }
        System.out.println(ans);
        input.close();
    }
}

Python代码

from collections import deque
import heapq
import sys
input = sys.stdin.readline
 
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
n, m = map(int, input().split())
a = [[0] * n for _ in range(m)]
done = [[False] * n for _ in range(m)]
 
Q = []
for j in range(n):
    row_a = list(map(int, input().split()))
    for i in range(m):
        a[i][j] = row_a[i]
        if a[i][j] <= 1:  done[i][j]=True
        else:             heapq.heappush(Q, (-a[i][j], i, j)) 
ans = 0 
while Q:
    _, sx, sy = heapq.heappop(Q)
    if not done[sx][sy]:
        ans += 1
        q = deque([(sx, sy)])
        done[sx][sy] = True 
        while q:
            x, y = q.popleft()
            for i in range(4):
                nx, ny = x + dx[i], y + dy[i]
                if 0 <= nx < m and 0 <= ny < n and not done[nx][ny] and a[nx][ny] <= a[x][y]:
                    q.append((nx, ny))
                    done[nx][ny] = True
print(ans)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/868440.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用python对图像加噪声

加上雨点噪声 import cv2 import numpy as npdef get_noise(img, value10):#生成噪声图像>>> 输入&#xff1a; img图像value 大小控制雨滴的多少 >>> 返回图像大小的模糊噪声图像noise np.random.uniform(0, 256, img.shape[0:2])# 控制噪声水平&#xff…

Arduino ESP32 v2 使用记录:开发环境搭建

文章目录 目的开发环境搭建程序下载测试使用VS Code进行开发批量烧录固件到模块中总结 目的 在之前的文章 《使用Arduino开发ESP32&#xff08;01&#xff09;&#xff1a;开发环境搭建》 中介绍了使用Arduino开发ESP32的开发环境搭建内容&#xff0c;只不过当时的 Arduino co…

写一个函数返回参数二进制中 1 的个数(c语言三种实现方法)

&#xff08;本文旨在自己做题时的总结&#xff0c;我会给出不同的解法&#xff0c;后面如果碰到新的题目还会加入其中&#xff0c;等于是我自己的题库。 1.写一个函数返回参数二进制中 1 的个数。 比如&#xff1a; 15 0000 1111 4 个 1 方法一&#xff1a; #include…

Kubernetes 调度约束(亲和性、污点、容忍)

目录 一、Pod启动典型创建过程 二、调度流程 三、指定调度节点 1.使用nodeName字段指定调度节点 2.使用nodeSelector指定调度节点 2.1给对应的node节点添加标签 2.2修改为nodeSelector调度方式 3.通过亲和性来指定调度节点 3.1节点亲和性 3.2Pod亲和性与反亲和性 3.2…

SAP MM学习笔记18- SQVI 工具

Tr-cd SQVI 是一个SAP数据库工具。 使用这个工具&#xff0c;可以自己构建查询界面中的条件&#xff0c;查询对象&#xff0c;从而自由查询数据&#xff0c;实现标准没有的功能。 1&#xff0c;SQVI 和 SQ1&#xff0c;SQ2&#xff0c;SQ3 的不同 SQ1&#xff0c;2&#xff0…

【hello C++】智能指针

目录 一、内存泄漏 1.1 什么是内存泄漏&#xff0c;内存泄漏的危害 1.2 内存泄漏分类 1.3 如何检测内存泄漏 1.4 如何避免内存泄漏 二、智能指针的使用及原理 2.1 RAII 2.2 智能指针的原理 2.3 智能指针的发展历程 2.4 智能指针的模拟及实现 三、shared_ptr 常见的问题 3.1 线程…

10.pod资源限制和健康检查

文章目录 资源限制探针&#xff08;健康检查&#xff09;启动、退出动作总结 资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。当为 pod 中的容器指定了 request 资源时&#xff0c…

5. vue-element-admin 二次开发攻略指南

vue-element-admin一站式后端 UI框架二次开发攻略指南 1.1 前言1.2 修改 Logo 名称和图标1.3 控制设置齿轮是否显示或隐藏1.4 框架安装依赖优化脚本1.5 定义多环境配置文件1.6 优化打包流程1.7 优化打包流程输出文件路径配置1.8 nginx 配置1.9 docker file 配置 2. 代码地址 1.…

计算机网络-专业术语

计算机网络-专业术语 实体 实体:任何可发送或接收信息的硬件或软件进程 对等实体:收发双方相同层次中的实体 协议 控制两个对等实体进行逻辑通信的规则的集合 协议三要素 语法 定义所交换的信息的格式 是用户数据与控制信息的结构和格式 语义 定义收发双方所需要完成的操作…

STM32CubeMX之freeRTOS信号量

队列可以传输数据&#xff0c;任务之间和任务和中断之间&#xff0c;消息队列用来传数据&#xff0c;占用时间也长 但哦我们有时候只需要传递状态&#xff0c;只需要一个数值表示 如果我们屏幕按固定刷新&#xff0c;就会很消耗资源&#xff0c;如果我们数据变化了&#xff0…

Hadoop+Python+Django+Mysql热门旅游景点数据分析系统的设计与实现(包含设计报告)

系统阐述的是使用热门旅游景点数据分析系统的设计与实现&#xff0c;对于Python、B/S结构、MySql进行了较为深入的学习与应用。主要针对系统的设计&#xff0c;描述&#xff0c;实现和分析与测试方面来表明开发的过程。开发中使用了 django框架和MySql数据库技术搭建系统的整体…

人工智能讲师AIGC讲师叶梓:大模型这么火,我们在使用时应该关注些什么?-2

以下为叶老师讲义分享&#xff1a; P6-P9 一些考验大模型的经典问题: 1、鲁迅与周树人是同一个人吗?2、圆周率的最后一位3、蓝牙耳机坏了4、最新的&#xff1a;奶奶的睡前故事 关于事实的问答结果: 知识的时效性&#xff1a; 未完&#xff0c;下一章继续……

java程序打包成exe在无java环境执行

最近写了个小工具&#xff0c;但是java写的&#xff0c;给朋友用的时候不能直接用&#xff0c;因此学习了一下java打包成exe。 众所周知&#xff0c;java需要jvm环境&#xff0c;所以打包的时候需要把稍微轻一点的jre打包进去。接下来是详细步骤。 java程序打包成jar 这个在…

C#随机法 双峰函数 求极值 避免落入局部最优解

避免落入局部最优解&#xff0c;只要让步长够长即可。 x1 resultX1 random1.NextDouble()*100; 如果后面不乘以100&#xff0c;则很大概率落入负数的最大值 Random random1 new Random(DateTime.Now.Millisecond);double x1 0, resultX10,max-999999,maxTemp0;for (int i …

【学会动态规划】买卖股票的最佳时机 III(17)

目录 动态规划怎么学&#xff1f; 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后&#xff1a; 动态规划怎么学&#xff1f; 学习一个算法没有捷径&#xff0c;更何况是学习动态规划&#xff0c; 跟我…

骨传导耳机对人体有什么危害,骨传导耳机优缺点是什么?

骨传导耳机对人体有没有伤害&#xff1f; 骨传导耳机的专属挂耳式佩戴方式&#xff0c;不需要将耳机塞入耳朵或者是住整个耳朵&#xff0c;开放双耳的全新佩戴体验&#xff0c;在听音乐的同时不会屏蔽我们的耳朵提取其它信息&#xff0c;能让我们及时听到周围环境音&#xff0c…

tensorRT_Pro 项目实践

参考&#xff1a;https://github.com/shouxieai/tensorRT_Pro/blob/main/tutorial/README.zh-cn.md 前提&#xff1a; https://www.cnblogs.com/odesey/p/17619218.html https://www.cnblogs.com/odesey/p/17619240.html ubuntu20.04opencv4.2cuda11.8cuDNN v8.9.0 (July 1…

【Python】背景及环境搭建

文章目录 了解计算机一、Python背景知识一、Python环境搭建 努力经营当下 直至未来明朗 了解计算机 示例&#xff1a;使用电脑访问B站 1&#xff09; 本地的计算机会给B站服务器发送一个网络请求&#xff08;如&#xff1a;谁&#xff0c;想看哪个视频&#xff09; 2&#xf…

WPS Office 代码执行漏洞(QVD-2023-17241)

目录 本地利用弹计算器&#xff08;自娱自乐&#xff09; 原理分析 msf的利用 1.修改win11中的hosts文件 2.MSF生成一个C#后门 3.shellcode替换 4.在创建html的目录&#xff0c;用python打开http服务来捕获请求 5.开启监听 6.在win11中点击poc文档&#xff0c;可以看到k…

0001nginx简介、相关模型与原理

文章目录 一. 什么是Nginx二. ngnix的一些模型1、nginx的进程模型2、worker的抢占&#xff08;锁&#xff09;机制模型3. nginx事件处理模型 三. nginx加载静态资源的过程 一. 什么是Nginx Nginx是一个高性能HTTP反向代理服务器&#xff0c;以下是nginx的相关能力 反向代理&am…