UVA 221 - Urban Elevations(离散化)!!!!!!

时间:2022-09-10 13:22:28

题意:给出一张俯视图。给出N个建筑物的左下标,长度,宽度,高度。现在求,从南面看,能看到那些建筑?

Sample Input

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
0

Sample Output

For map #1, the visible buildings are numbered as follows:
5 9 4 3 10 2 1 14
unique()函数
是一个去重函数,STL中unique的函数 unique的功能是去除相邻的重复元素(只保留一个)
还有一个容易忽视的特性是它并不真正把重复的元素删除。
eg.
int num[100];
 unique(num,mun+n)返回的是num去重后的尾地址,之所以说比不真正把重复的元素删除,其实是,该函数把重复的元素一到后面去了,
然后依然保存到了原数组中,然后返回去重后最后一个元素的地址,因为unique去除的是相邻的重复元素,所以一般用之前都会要排一下序。

离散化

基本思想就是在众多可能的情况中“只考虑我需要用的值”。

eg.1

给定平面上n个点的坐标,求能够覆盖所有这些点的最小矩形面积。这个问题难就难在,这个矩形可以倾斜放置(边不必平行于坐标轴)。

UVA 221 - Urban Elevations(离散化)!!!!!!

这里的倾斜放置很不好处理,因为我们不知道这个矩形最终会倾斜多少度。假设我们知道这个矩形的倾角是α,那么答案就很简单了:

矩形面积最小时四条边一定都挨着某个点。也就是说,四条边的斜率已经都知道了的话,只需要让这些边从外面不断逼近这个点集直到碰到了某个点。

你不必知道这个具体应该怎么实现,只需要理解这可以通过某种方法计算出来,毕竟我们的重点在下面的过程。

我们的算法很显然了:枚举矩形的倾角,对于每一个倾角,我们都能计算出最小的矩形面积,最后取一个最小值。

这个算法是否是正确的呢?我们不能说它是否正确,因为它根本不可能实现。矩形的倾角是一个实数,它有无数种可能,你永远不可能枚举每一种情况。我们说,矩形的倾角是一个“连续的”变量,它是我们无法枚举这个倾角的根本原因。我们需要一种方法,把这个“连续的”变量变成一个一个的值,变成一个“离散的”变量。这个过程也就是所谓的离散化。
    我们可以证明,最小面积的矩形不但要求四条边上都有一个点,而且还要求至少一条边上有两个或两个以上的点。试想,如果每条边上都只有一个点,则我们总可以把这个矩形旋转一点使得这个矩形变“松”,从而有余地得到更小的矩形。于是我们发现,矩形的某条边的斜率必然与某两点的连线相同。如果我们计算出了所有过两点的直线的倾角,那么α的取值只有可能是这些倾角或它减去90度后的角(直线按“\”方向倾斜时)这么C(n,2)种。我们说,这个“倾角”已经被我们 “离散化”了。虽然这个算法仍然有优化的余地,但此时我们已经达到了本文开头所说的目的。

eg.2

大意是给定平面上的n个矩形(坐标为整数,矩形与矩形之间可能有重叠的部分),求其覆盖的总面积。平常的想法就是开一个与二维坐标规模相当的二维Boolean数组模拟矩形的“覆盖”(把矩形所在的位置填上True)。可惜这个想法在这里有些问题,因为这个题目中坐标范围相当大(坐标范围为-10^8到10^8之间的整数)。但我们发现,矩形的数量n<=100远远小于坐标范围。每个矩形会在横纵坐标上各“使用”两个值,  100个矩形的坐标也不过用了-10^8到10^8之间的200个值。也就是说,实际有用的值其实只有这么几个。这些值将作为新的坐标值重新划分整个平面,省去中间的若干坐标值没有影响。我们可以将坐标范围“离散化”到1到200之间的数,于是一个200*200的二维数组就足够了。实现方法正如本文开头所说的“排序后处理”。对横坐标(或纵坐标)进行一次排序并映射为1到2n的整数,同时记录新坐标的每两个相邻坐标之间在离散化前实际的距离是多少。这道题同样有优化的余地。

UVA 221 - Urban Elevations(离散化)!!!!!!

 
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn=+; struct Building{
int id;
double x,y,w,d,h;
bool operator < (const Building& rhs) const{ //重载运算符<
return x<rhs.x||(x==rhs.x&&y<rhs.y); // true x未被rhs挡住(x在rhs.x的左边 或者 x与rhs.x相同,但x在rhs.x前面,即y<rhs.y)
}
}b[maxn]; int n;
double x[maxn*]; //用来存储各个建筑物的左右边界 bool cover(int i,double mx) //判断建筑物i在x=mx处是否可见
{
return b[i].x<=mx&&b[i].x+b[i].w>=mx; //true时 b[i]在mx处可见
} bool visible(int i,double mx)
{
if(!cover(i,mx))return false; //b[i]在mx处不可见
for(int k=;k<n;k++)
if(b[k].y<b[i].y&&b[k].h>=b[i].h&&cover(k,mx))return false; //b[i]被b[k]挡住
return true; //b[i]在mx处可见
} int main()
{
int kase=;
while(scanf("%d",&n)==&&n){ //n个建筑
for(int i=;i<n;i++){
scanf("%lf%lf%lf%lf%lf",&b[i].x,&b[i].y,&b[i].w,&b[i].d,&b[i].h);
x[i*]=b[i].x; //建筑左边界
x[i*+]=b[i].x+b[i].w; //建筑右边界
b[i].id=i+;
}
sort(b,b+n); //按照结构体中重载的运算符<排序,x小的在前面,x相同y小的在前面
/*cout<<endl;
for(int i=0;i<n;i++)
cout<<b[i].id<<" "<<b[i].x<<" "<<b[i].y<<" "<<b[i].h<<" "<<b[i].d<<endl;*/
sort(x,x+n*);
int m=unique(x,x+n*)-x; //x坐标排序后去重,得到m个坐标
//x的前m项为建筑群从左到右的左边界有边界
//for(int i=0;i<n*2;i++)cout<<x[i]<<endl;
if(kase++)printf("\n");
printf("For map #%d,the visible buildings are numbered as follows:\n%d",kase,b[].id); //左下角的建筑肯定可以看到
for(int i=;i<n;i++){
bool vis=false;
for(int j=;j<m-;j++){
if(b[i].x+b[i].w<x[j])break; //增添这句后,简化程序,当b[i]建筑的右边界都小于x[j]时在其中点处肯定不可见
if(visible(i,(x[j]+x[j+])/)){ //true b[i]在各个左右边界之间的中点处可见
vis=true;
break;
}
}
if(vis)printf(" %d",b[i].id);
}
printf("\n");
}
//system("pause");
return ;
}

 

UVA 221 - Urban Elevations(离散化)!!!!!!的更多相关文章

  1. UVa 221 Urban Elevations 城市正视图 离散化初步 无限化有限

    转载请注明: 仰望高端玩家的小清新 http://www.cnblogs.com/luruiyuan/ 题目大意: 题目传送门:UVa 221 Urban Elevations 给出城市中建筑物的x, ...

  2. UVA 221 Urban Elevations

    思路: 一些解释: ①:建筑的排序: 下面是以输入顺序为标号,在数组bd中的顺序: 排序后在数组bd中的顺序: 以后我们比较就按这个顺序 ②:x坐标的排序 x的内容是每一个建筑的左边界和右边界,我们把 ...

  3. X - Urban Elevations

     Urban Elevations  An elevation of a collection of buildings is an orthogonal projection of the buil ...

  4. UVa 221 &lpar;STL 离散化&rpar; Urban Elevations

    题意: 作图为n个建筑物的俯视图,右图为从南向北看的正视图,按从左往右的顺序输出可见建筑物的标号. 分析: 题中已经说了,要么x相同,要么x相差足够大,不会出现精度问题. 给这n个建筑物从左往右排序, ...

  5. 【紫书】Urban Elevations UVA - 221 离散化

    题意:给你俯视图,要求依次输出正视图中可以看到的建筑物 题解:任意相邻的x间属性相同,所以离散化. 坑:unique只能对数组用.下标易错 list不能找某元素的next.用了个很麻烦的处理 数组: ...

  6. Urban Elevations UVA - 221

    题目大意:给出建筑的俯视图,以及每个建筑的左下角坐标,宽度,长度,高度.求正视图可观察到的建筑的编号 思路:建筑物的可见性等于南墙的可见性,依据左下角排序后,逐个判断每个建筑是否可见.对南墙的x坐标进 ...

  7. UVa 221城市正视图(离散化)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. UVA 221 城市化地图(离散化思想)

    题意: 给出若干个栋楼俯视图的坐标和面积,求从俯视图的南面(可以视为正视图)看过去到底能看到多少栋楼. 输入第一个n说明有n栋楼,然后输入5个实数(注意是实数),分别是楼的左下角坐标(x,y), 然后 ...

  9. hdu 2771&lpar;uva 12171&rpar; Sculpture bfs&plus;离散化

    题意: 给出一些边平行于坐标轴的长方体,这些长方体可能相交.也可能相互嵌套.这些长方体形成了一个雕塑,求这个雕塑的整体积和表面积. 题解: 最easy想到直接进行bfs或者dfs统计,但此题的麻烦之处 ...

随机推荐

  1. MYSQL离线安装

    由于MySQL的广泛应用,MySQL的安装也就成了大家经常会碰到的问题.并且由于不是所有机器都可连接外网,所以MySQL的离线安装显得比较重要.而本文旨在介绍CentOS6.6下离线安装MySQL. ...

  2. python数据库(mysql)操作

    http://fantefei.blog.51cto.com/2229719/1282443

  3. href&equals;&num;与href&equals;javascriptvoid&lpar;0&rpar;的区别

    #"包含了一个位置信息 默认的锚点是#top 也就是网页的上端 而javascript:void(0)  仅仅表示一个死链接 这就是为什么有的时候页面很长浏览链接明明是#可是跳动到了页首 而 ...

  4. javascript-对象的函数&lpar;一&rpar;

    Date.prototype.Format = function(fmt) { //author: meizz var o = { "M+" : this.getMonth()+1 ...

  5. 武汉科技大学ACM:1006&colon; 我是老大

    Problem Description 今年是2021年,正值武汉科技大学 ACM俱乐部成立10周年.十周年庆祝那天,从ACM俱乐部走出去的各路牛人欢聚一堂,其乐融融.庆祝晚会上,大家纷纷向俱乐部伸出 ...

  6. R与数据分析旧笔记(一)基本数学函数的使用

    创建向量矩阵 > x1=c(2,3,6,8) > x2=c(1,2,3,4) > a1=(1:100) > length(a1) [1] 100 > length(x1) ...

  7. Python之编程基础(编程语言分类)

    一.编程语言简介 编程语言主要从以下几个角度进行分类,编译型和解释型.静态语言和动态语言.强类型定义语言和弱类型定义语言. 1.编译型跟解释型 编译型,其实他和汇编语言是一样的,也是有一个负责翻译的程 ...

  8. SVN的Not authorized to open root of edit operation解决办法

    以为经常用到这是转贴  谢谢 Subversion装了1.5.2版,乌龟SVN装的是1.5.1版本,可以通过乌龟正常访问到版本库,但当check out时却出现了"Not authorize ...

  9. IDEA 构建为了打 jar 包的工程,包含 maven 打 jar 包的过程

    前言:最近自己写了一个单表查询的组件,包含前端.后台,所以需要向阿里的 druid 一样将所有文件打到一个 jar 包里,这里首先记录如何打 jar 包. 附:自己的一个 jar 包源码 https: ...

  10. ubuntu18&period;04下监视显卡的运行情况【学习笔记】

    作者:庄泽彬(欢迎转载,请注明作者) 说明:使用watch命令监听显卡的使用 安装完显卡驱动之后系统会生成nvidia-smi 这个工具,我们只需要配合watch命令就可以周期性的查看显卡的信息,-n ...