NYOJ squares(计算几何+区间覆盖)

2023-12-06 09:32

本文主要是介绍NYOJ squares(计算几何+区间覆盖),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

描述
In this problem, you are given a sequence S1, S2, ..., Sn of squares of different sizes. The sides of the squares are integer numbers. We locate the squares on the positive x-y quarter of the plane, such that their sides make 45 degrees with x and y axes, and one of their vertices are on y=0 line. Let bi be the x coordinates of the bottom vertex of Si. First, put S1 such that its left vertex lies on x=0. Then, put S1, (i > 1) at minimum bi such that
bi > bi-1 and
the interior of Si does not have intersection with the interior of S1...Si-1.
The goal is to find which squares are visible, either entirely or partially, when viewed from above. In the example above, the squares S1, S2, and S4 have this property. More formally, Si is visible from above if it contains a point p, such that no square other than Si intersect the vertical half-line drawn from p upwards.
输入
The input consists of multiple test cases. The first line of each test case is n (1 ≤ n ≤ 50), the number of squares. The second line contains n integers between 1 to 30, where the ith number is the length of the sides of Si. The input is terminated by a line containing a zero number.
输出
For each test case, output a single line containing the index of the visible squares in the input sequence, in ascending order, separated by blank characters.
样例输入
4
3 5 1 4
3
2 1 2
0
样例输出
1 2 4

1 3

 

其实清楚一看就会发现其实每个正方形都对应一条线段,这个线段就是横向的对角线。所以问题就转化成求线段的覆盖问题,看哪些线段被盖住了。求线段覆盖的时候应为题目数据的要求范围很低,直接暴力随便什么的应该都没有问题,但是要注意一点,线段覆盖之前要先排序一下,因为哪根线段先放结果是不一样的。但我们又可以发现边长小的对角线一定在下面,所以考虑的时候应先按照边长的大小排序一下。接着我们再看一条线段是怎么确定的?其实就是左右端点,根据题目给的整数长度的边长,你会发现求出来的是浮点数的一条线段,浮点数是会产生误差的,之后判断的时候会误差,所以这其实需要一个巧妙的转化,就是说我们把正方行边长扩大sqrt(2),这就成为了数学中的相似,对结果是不影响的,仅相当于整个图都扩大了。

设当前的正方形为b, 紧挨着的前一个为f,扩大sqrt(2)倍的左右端点分别为b.l,f.l以及f.r, b.r,   b.len, f.len是原输入数据的正方形的边长大小, 则有等式b.l=f.r-abs(b.len-f.len), b.r=b.l+2*b.len,这是简单几何,细心看一下就会发现,到此,这题应该就差不多了

 

AC代码:

 

 

# include <cstdio>
# include <cmath>
# include <cstdlib>
# include <cstring>
# include <algorithm>
using namespace std;
struct node{int r, l, len ,no;//左右端点,长度及其编号//r, l是扩大sqrt(2)后的左右端点距离,len是原数据长度 
};
node s[60];
int ans[60];
int compare(node a, node b){return a.len<b.len;//边长最小最下面 ,排序一下 
}
int main(){int n, i, j, k, Max_r, Min_l, cnt;while(scanf("%d", &n)!=EOF){if(n==0){break;}for(i=1; i<=n; i++){scanf("%d", &s[i].len);//输入数据 s[i].no=i;}cnt=0;//初始化s[1].l=0;s[1].r=2*s[1].len;Max_r=s[1].r;for(i=2; i<=n; i++){s[i].l=0;for(j=1; j<i; j++){s[i].l=max(s[i].l, s[j].r-abs(s[i].len-s[j].len));//枚举可能在第i个图形前面的正方形,更新Max_r }s[i].r=s[i].l+2*s[i].len;Max_r=max(Max_r, s[i].r);}sort(s+1, s+1+n, compare);//按边长排序一下 for(i=1; i<=n; i++){for(j=1; j<i; j++){if(s[j].l>=s[j].r){continue;}if(s[i].l<=s[j].l&&s[i].r>=s[j].r){s[j].r=s[j].l;}else if(s[i].l<=s[j].l&&s[i].r<=s[j].r&&s[i].r>=s[j].l){s[j].l=s[i].r;}else if(s[i].l>=s[j].l&&s[i].r>=s[j].r&&s[i].l<=s[j].r){s[j].r=s[i].l;}}}for(i=1; i<=n; i++){//满足要求的,记录编号 if(s[i].r>s[i].l){ans[cnt++]=s[i].no;}}sort(ans, ans+cnt);//按编号排序一下,最后再输出 for(i=0; i<=cnt-1; i++){if(i!=cnt-1){printf("%d ", ans[i]);}else{printf("%d\n", ans[i]);}}}return 0;
}

 

 

 

 

 

这篇关于NYOJ squares(计算几何+区间覆盖)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/461345

相关文章

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

Python绘制土地利用和土地覆盖类型图示例详解

《Python绘制土地利用和土地覆盖类型图示例详解》本文介绍了如何使用Python绘制土地利用和土地覆盖类型图,并提供了详细的代码示例,通过安装所需的库,准备地理数据,使用geopandas和matp... 目录一、所需库的安装二、数据准备三、绘制土地利用和土地覆盖类型图四、代码解释五、其他可视化形式1.

如何用Java结合经纬度位置计算目标点的日出日落时间详解

《如何用Java结合经纬度位置计算目标点的日出日落时间详解》这篇文章主详细讲解了如何基于目标点的经纬度计算日出日落时间,提供了在线API和Java库两种计算方法,并通过实际案例展示了其应用,需要的朋友... 目录前言一、应用示例1、天安门升旗时间2、湖南省日出日落信息二、Java日出日落计算1、在线API2

usaco 1.2 Palindromic Squares(进制转化)

考察进制转化 注意一些细节就可以了 直接上代码: /*ID: who jayLANG: C++TASK: palsquare*/#include<stdio.h>int x[20],xlen,y[20],ylen,B;void change(int n){int m;m=n;xlen=0;while(m){x[++xlen]=m%B;m/=B;}m=n*n;ylen=0;whi

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc