[题解]POJ2074 Line of Sight
题意简述

多测。给定若干条线段,全部与\(x\)轴平行。
其中有\(2\)条线段表示房子和人行道(虽然翻译不是人行道就是了),保证房子在人行道上面。
其他线段表示障碍物(不保证在房子和人行道之间)。
请找出人行道上最长的连续部分,使得在这中间可以完整地看到房子的全貌。
如果存在,输出其长度即可,保留\(2\)位小数;如果不存在输出No View。
数据范围没给,不过开\(10^5\)能过。具体输入格式见题目。
思路分析
先以人行道的左端点为\((0,0)\),将所有坐标整体移动一下,方便考虑。
我们发现想直接计算能看到的区域比较困难,但是可以计算出每个障碍物形成的盲区:

如图,盲区就是房子的左右端点和障碍物的右左端点(注意顺序)连接并延长,与人行道相交形成的线段。
我们对每个障碍物,计算盲区的左右端点(计算射线和直线的交点,具体见代码)并储存。注意盲区的左右端点可能超出边界,所以需要取一下\(\min,\max\)。
我们注意到盲区可能发生重叠,所以需要把重叠部分进行合并,方便计算。
具体方法嘛,就是把盲区按左端点从小到大排序。如果后一个盲区的左端点\(<\)前一个盲区的右端点,就更新前一个盲区的右端点,并且删除后一个盲区。代码使用STL的链表实现。
合并完再遍历一遍,计算最大值即可求出答案。注意遍历前还需要把\((0,0),(len,len)\)分别加到链表的头和尾,因为左右边界也可能存在非盲区。
就酱。
思路并不难,不过代码实现有一些细节需要注意:
盲区左右端点可能超出边界,需要取一下\(\min,\max\)。
合并完盲区,需要额外把\((0,0),(len,len)\)分别加到链表的开头和结尾。
对于所有障碍物,如果其\(y\)坐标\(\ge\)房子的\(y\)坐标,或者\(<\)人行道的\(y\)坐标,就不能参与考虑。注意这一判断与\(x\)坐标无关,就算障碍物完全在人行道外面,也可能在人行道上形成盲区。
遍历链表的过程中,可能会有删除操作。因此我们需要注意一下使用迭代器的方式:
for(auto it=lis.begin();it!=lis.end();){
if(/* 条件 */){
/* Something ... */
it=lis.erase(it);//lis.erase(it++)也可以
}else{
/* Something ... */
it++;
}
}
保留\(2\)位小数。
Code
POJ的编译器太老了,提交的代码需要经过一番修改。这里就不放修改后的代码了,毕竟重在理解嘛。
点击查看代码
#include<bits/stdc++.h>
#define N 100010
using namespace std;
struct tseg{double x1,x2,y;};
struct point{double x,y;};
tseg house,lin;
int n,siz;
double ans;
void modify(tseg &a){
a.x1-=lin.x1,a.x2-=lin.x1,a.y-=lin.y;
}//将a的绝对位置转为相对人行道的位置
list<pair<double,double>> segs;
double calc(point a,point b){
return a.x-a.y*(a.x-b.x)/(a.y-b.y);
}//计算射线AB与x轴的交点
int main(){
while(cin>>house.x1>>house.x2>>house.y){
segs.clear(),ans=0;
if(house.x1==house.x2&&house.x2==house.y&&house.y==0) break;
cin>>lin.x1>>lin.x2>>lin.y>>n;
modify(house);
double len=lin.x2-lin.x1;
for(int i=1;i<=n;i++){
tseg ta;
cin>>ta.x1>>ta.x2>>ta.y;
modify(ta);
if(ta.y>=house.y||ta.y<0) continue;
double x1=calc({house.x1,house.y},{ta.x2,ta.y});
double x2=calc({house.x2,house.y},{ta.x1,ta.y});
segs.push_back({min(len,max(0.0,x2)),min(len,max(0.0,x1))});
}//注意x1,x2需要反序,x2实际是左端点
segs.sort();
for(auto it=segs.begin(),lastit=segs.end();it!=segs.end();){
if(lastit!=segs.end()&&(*lastit).second>=(*it).first){
(*lastit).second=max((*lastit).second,(*it).second);
it=segs.erase(it);
}else lastit=it,it++;
}//合并盲区,注意特殊的迭代器写法
segs.push_front({0,0});
segs.push_back({len,len});
for(auto it=segs.begin(),lastit=segs.end();it!=segs.end();lastit=it,it++){
if(it==segs.begin()) continue;
ans=max(ans,(*it).first-(*lastit).second);
}
if(ans==0) cout<<"No View\n";
else cout<<fixed<<setprecision(2)<<ans<<"\n";
}
return 0;
}
[题解]POJ2074 Line of Sight的更多相关文章
- POJ2074 Line of Sight
嘟嘟嘟 题意:用一条水平线段表示以栋房子:\((x_0, y_0)(x_0', y_0)\).然后有一条低于房子的水平线段\(l_0\),代表你可以到的位置.接下来输入一个数\(n\),一下\(n\) ...
- Poj 2074 Line of Sight
地址:http://poj.org/problem?id=2074 题目: Line of Sight Time Limit: 1000MS Memory Limit: 30000K Total ...
- unity下的Line of Sight(LOS)的绘制
先说说什么是Linf of Sight.在很多RTS游戏中,单位与单位之间的视野关系经常会受到障碍物遮挡.Line of Sight指的就是两个物体之间是否没有障碍物遮挡. 比如在dota中,玩家的视 ...
- 【转】Using Raycasts and Dynamically Generated Geometry to Create a Line of Sight on Unity3D
http://www.linkedin.com/pulse/using-raycasts-dynamically-generated-geometry-create-line-thomas José ...
- 【转】unity下的Line of Sight(LOS)的绘制
http://www.cnblogs.com/yangrouchuan/p/6366629.html 先说说什么是Linf of Sight.在很多RTS游戏中,单位与单位之间的视野关系经常会受到障碍 ...
- POJ2074:Line of Sight——题解
http://poj.org/problem?id=2074 题目大意:(下面的线段都与x轴平行)给两条线段,一个点在其中一条线段看另一条线段,但是中间有很多线段阻挡视线.求在线段上最大连续区间使得在 ...
- G - Line of Sight
来源poj2074 An architect is very proud of his new home and wants to be sure it can be seen by people p ...
- 简单几何(直线求交点) POJ 2074 Line of Sight
题目传送门 题意:从一条马路(线段)看对面的房子(线段),问连续的能看到房子全部的最长区间 分析:自己的思路WA了:先对障碍物根据坐标排序,然后在相邻的障碍物的间隔找到区间,这样还要判断是否被其他障碍 ...
- poj 2074 Line of Sight 计算几何
/** 大意:给定一个建筑--水平放置,给定n个障碍物, 给定一条街道,从街道上能看到整个建筑的最长的连续的区域 思路: 分别确定每一个障碍物所确立的盲区,即----建筑物的终点与障碍物的起点的连线, ...
- [poj] 2074 Line of Sight || 直线相交求交点
原题 给出一个房子(线段)的端点坐标,和一条路的两端坐标,给出一些障碍物(线段)的两端坐标.问在路上能看到完整房子的最大连续长度是多长. 将障碍物按左端点坐标排序,然后用房子的右端与障碍物的左端连线, ...
随机推荐
- 处理日期和时间的chrono库
C++11中提供了日期和时间相关的库chrono,通过chrono库可以很方便地处理日期和时间,为程序的开发提供了便利.chrono库主要包含三种类型的类:时间间隔duration.时钟clocks. ...
- 【中英】【吴恩达课后测验】Course 5 -序列模型 - 第二周测验 - 自然语言处理与词嵌入
[中英][吴恩达课后测验]Course 5 -序列模型 - 第二周测验 - 自然语言处理与词嵌入 上一篇:[课程5 - 第一周编程作业]※※※※※ [回到目录]※※※※※下一篇:[课程5 -第二周编程 ...
- shell 脚本使用绝对路径
shell 脚本要使用绝对路径,不要在脚本中使用相对路径,使用相对路径的话脚本执行有可能在根目录,找到相对路径的位置
- git-intelligence-message 1.3.2 发布了,智能生成、提交git的工具
git-intelligence-message 1.3.2 发布了,这是一次小版本更新.主要内容是可以通过命令查看AI配置信息了. Git Intelligence Message (GIM) 是一 ...
- K8s v1.31 新特性:ImageVolume,允许将镜像作为 Volume 进行挂载
本文主要分享一个 K8s 1.31 增加的一个新 Feature:ImageVolume.允许直接将 OCI 镜像作为 Volume 进行挂载,加速 artifact 分发. 1.背景 Kuberne ...
- INFINI Labs 产品更新 | Coco AI 0.5 发布 – 无缝集成 AI 搜索能力、支持插件扩展、支持快照版本更新等
INFINI Labs 产品更新发布!此次更新涵盖 Coco AI 产品多项重要升级,重点提升 AI 搜索能力.易用性及企业级优化. Coco AI v0.5 无缝集成 AI 搜索能力,支持第三方插件 ...
- C# 生成一天内不重复的int 值
public static int ConvertDateTimeToInt(System.DateTime time) { System.DateTime sta ...
- wifi转串口的模块
wifi转串口的模块ZLSN7046T是上海卓岚生产的一款多功能wifi转串口模块.它能够将wifi信号转化为串口信号,且支持多种功能,邮票孔封装,体积小巧可以外置天线或者内置天线.ZLAN7046T ...
- CF2092F Andryusha and CCB 题解
CF2092F Andryusha and CCB CF 官解感觉跳了很多步啊,自己写一篇造福后人. 首先肯定是不能直接求的,考虑转化贡献体.对划分的段数转化贡献依旧不好求,考虑对每个子串的美感度转化 ...
- apt 相关操作
apt-cache search XXX 寻找相关的包 apt-cache showpkg XXX 显示相关包的信息 sudo apt-get --purge remove *** 移除相关的包 dp ...