城市正视图(Urban Elevations, ACM/ICPC World Finals 1992, UVa221)rust解法

news/2025/3/14 5:30:49/

如图5-4所示,有n(n≤100)个建筑物。左侧是俯视图(左上角为建筑物编号,右下角为高度),右侧是从南向北看的正视图。
在这里插入图片描述
输入每个建筑物左下角坐标(即x、y坐标的最小值)、宽度(即x方向的长度)、深度(即y方向的长度)和高度(以上数据均为实数),输出正视图中能看到的所有建筑物,按照左下角x坐标从小到大进行排序。左下角x坐标相同时,按y坐标从小到大排序。输入保证不同的x坐标不会很接近(即任意两个x坐标要么完全相同,要么差别足够大,不会引起精度问题)。
【分析】
注意到建筑物的可见性等价于南墙的可见性,可以在输入之后直接忽略“深度”这个参数。
把所有建筑物按照左下角坐标排序,然后依次判断可见性。
判断可见性看上去比较麻烦,因为一个建筑物可能只有部分可见,无法枚举所有x坐标,因为x坐标是实数,所以有无穷多个。
解决方法是离散化,即把无穷变为有限。就是把每一个建筑物的两端的坐标x和x+w放进一个数组里,然后排序并去重,做完这些操作就相当于分割了如下的若干个区间。

区间具有如下性质:
1.该区间要么不存在建筑物,要么存在若干个建筑物。
2.在区间中的建筑物,一定会把区间给填满,不会出现建筑物只占区间部分空间的情况。
所以我们只需要对每个建筑物,检查每个区间,判断它是否在该区间中。根据区间性质,只需在这个区间里任选一个点(例如中点),就能判断出一个建筑物是否在整个区间内。如果建筑物在该区间中,那么再检查它前面是否有一个比它更高的在该区间的建筑物。

样例:
输入

14
160 0 30 60 30
125 0 32 28 60
95 0 27 28 40
70 35 19 55 90
0 0 60 35 80
0 40 29 20 60
35 40 25 45 80
0 67 25 20 50
0 92 90 20 80
95 38 55 12 50
95 60 60 13 30
95 80 45 25 50
165 65 15 15 25
165 85 10 15 35

输出

5
9
4
3
10
2
1
14

解法:

use std::io;
#[derive(Debug, Clone, Copy)]
struct Building {pos: (f64, f64),w: f64,d: f64,h: f64,id: usize,
}
fn main() {let mut buf = String::new();io::stdin().read_line(&mut buf).unwrap();let n: usize = buf.trim().parse().unwrap();let mut buildings: Vec<Building> = vec![];let mut xpoint: Vec<f64> = vec![];for i in 0..n {let mut buf = String::new();io::stdin().read_line(&mut buf).unwrap();let v: Vec<f64> = buf.split_whitespace().map(|e| e.parse().unwrap()).collect();let b = Building {pos: (v[0], v[1]),w: v[2],d: v[3],h: v[4],id: i + 1,};buildings.push(b);xpoint.push(b.pos.0);xpoint.push(b.pos.0 + b.w);}//println!("{:?}", buildings);buildings.sort_by(|a, b| a.pos.partial_cmp(&b.pos).unwrap());xpoint.sort_by(|a, b| a.partial_cmp(b).unwrap());xpoint.dedup();//println!("{:?}", buildings);//println!("{:?}", xpoint);for i in 0..n {let mut bvis = false;for j in 0..xpoint.len() - 1 {if is_visible(&buildings, i, (xpoint[j], xpoint[j + 1])) {bvis = true;break;}}if bvis {println!("{}", buildings[i].id);}}
}fn is_visible(buildings: &Vec<Building>, i: usize, interval: (f64, f64)) -> bool {if !is_in_interval(buildings, i, interval) {return false;}for k in 0..buildings.len() {if buildings[i].pos.1 > buildings[k].pos.1&& buildings[i].h <= buildings[k].h&& is_in_interval(buildings, k, interval){return false;}}return true;
}
fn is_in_interval(buildings: &Vec<Building>, i: usize, interval: (f64, f64)) -> bool {let mid = (interval.0 + interval.1) / 2.0;return mid >= buildings[i].pos.0 && mid <= buildings[i].pos.0 + buildings[i].w;
}

http://www.ppmy.cn/news/1171362.html

相关文章

几种基本的高斯分布数学运算,加法、乘法、缩放和卷积及运用场景

文章目录 高斯分布进行乘法运算几种基本的数学运算上述这些运算可以运用与什么场景?高斯分布进行乘法运算 当两个高斯分布进行乘法运算时,这通常是在估计或滤波的上下文中,如在卡尔曼滤波中的更新步骤。为了理解背后的数学原理,我们首先定义两个高斯分布: 当我们将这两个…

介绍Sigmoid函数的平移、平滑和翻转【基于Python可视化分析】

文章目录 简介Sigmoid函数Sigmoid函数曲线调控参数设置python可视化参考 简介 本篇博客介绍了具有S型曲线的Sigmoid函数&#xff0c;以及如何设置、调整Sigmoid函数的参数实现S曲线的平滑、平移和翻转操作。博客给出了Python代码示例&#xff0c;更加深刻形象。&#x1f606;&…

【已解决】ubuntu耳机单侧有声音

背景 台式机&#xff0c;双系统&#xff1a;win10 ubuntu 20.04&#xff1b;ubuntu 系统当中&#xff0c;左侧耳机有声音&#xff0c;右侧没有&#xff1b; 解决方法 终端输入&#xff1a;alsamixer&#xff0c;显示下面的图片&#xff1a; 调整方法&#xff1a;键盘上下左…

这Bug只能通过压测发现

大家好&#xff0c;我是洋子。之前发布过一篇有关于在性能测试当中发现Bug的文章《因为一个Bug&#xff0c;差点损失了100w》 这篇文章当时还登上了CSDN全站综合热榜TOP1&#xff0c;最近工作在做性能测试时&#xff0c;又发现了几个比较有意思得Bug&#xff0c;本期分享其中的…

Unity中Shader实现UI流光效果

文章目录 前言一、实现思路1&#xff1a;1、采集两张贴图&#xff0c;一张是主纹理&#xff0c;一张是扫光纹理2、在 v2f 定义一个二维变量 “uv2” 来存放 uv 偏移后的值3、在顶点着色器中&#xff0c;仿照之前的 uv 流动效果,与 _Time相乘后存放于 uv2 中4、最后&#xff0c;…

whois人员信息python批处理读入与文本输出

使用pytho读取一个ip列表文本&#xff0c;批量获取whois输出并写入到一个文本 import socketif __name__ __main__:# 江苏电信DNS地址mylog open(whois.log, mode a,encodingutf-8)for line in open("ip.txt"):s socket.socket(socket.AF_INET, socket.SOCK_STR…

基于Django开发的图书管理推荐、电影推荐、课程推荐系统、大众点评店铺推荐系统、健身课程管理系统

基于Django开发的图书管理推荐、电影推荐、课程推荐系统、大众点评店铺推荐系统、健身课程管理系统、资讯推荐系统 一、简介 推荐系统的目的是信息过载所采用的措施&#xff0c;面对海量的数据&#xff0c;从中快速推荐出用户可能喜欢的物品。 推荐系统的方法有以下几种&…

【Python机器学习】零基础掌握QuadraticDiscriminantAnalysis判别分析

如何准确地区分不同种类的水果? 在日常生活中,人们经常面临需要区分不同种类物品的情况。以水果店为例,假设有一个水果店主希望通过水果的颜色、大小、重量和甜度等特征来自动区分出苹果、橙子和香蕉。 解决思路:收集一些水果的样本数据,包括颜色、大小、重量和甜度等。…