POJ2074 Line of Sight
嘟嘟嘟
题意:用一条水平线段表示以栋房子:\((x_0, y_0)(x_0', y_0)\)。然后有一条低于房子的水平线段\(l_0\),代表你可以到的位置。接下来输入一个数\(n\),一下\(n\)行每行\(3\)个数,用一条水平线段代表障碍物。求你在\(l_0\)上能看到房子的最大连续长度。(看到房子指房子完全没被挡上)
刚开始自己\(yy\)了一个\(O(n ^ 2)\)的算法,结果\(TLE\)了……谁叫这题不告诉我数据范围的。
正解比较有意思:我们要逆向思维:对于一个障碍物,求出它能遮挡的范围,那么最后的答案就是没被遮挡的区间长度的最大值。
遮挡的范围画个图就明白了:

则\([N, M]\)就是被遮挡的区间,然后用叉积求交点即可。
那么现在我们就得到了一堆区间(可能重叠),然后想括号匹配一样跑一边,如果当前栈空,就那\(a _ {i + 1} - a _ i\)更新答案。
需要注意的是\([N, M]\)可能在直线\(l_0\)之外,这时候那\(l_0\)两个端点限制\(N, M\)即可,具体看代码。
还有一点就是区间的头和尾的地方要单独算一下,即\(a _ 1 - L\)和\(R - a _ n\)
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 5e4 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n;
struct Vec
{
db x, y;
db operator * (const Vec& oth)const
{
return x * oth.y - oth.x * y;
}
};
struct Point
{
db x, y;
Vec operator - (const Point& oth)const
{
return (Vec){x - oth.x, y - oth.y};
}
}H1, H2, L1, L2;
struct Node
{
db x; int flg;
bool operator < (const Node& oth)const
{
return x < oth.x;
}
}a[maxn];
int cnt = 0;
void solve(Point A, Point B, int flg)
{
Vec AB = B - A;
Vec CA = A - L1, CD = L2 - L1, DB = B - L2;
db s1 = CA * CD, s2 = -(DB * CD);
db ret = A.x + AB.x / (s1 + s2) * s1;
if(ret > L2.x) ret = L2.x; //限制N, M
if(ret < L1.x) ret = L1.x;
a[++cnt] = (Node){ret, flg};
}
int main()
{
while(scanf("%lf%lf%lf", &H1.x, &H2.x, &H1.y))
{
if(H1.x == 0 && H1.y == 0 && H2.x == 0) break;
cnt = 0;
H2.y = H1.y;
scanf("%lf%lf%lf", &L1.x, &L2.x, &L1.y); L2.y = L1.y;
n = read();
for(int i = 1; i <= n; ++i)
{
db L, R, y;
scanf("%lf%lf%lf", &L, &R, &y);
if(y < L1.y || y >= H1.y) continue;
solve(H1, (Point){R, y}, -1);
solve(H2, (Point){L, y}, 1);
}
if(!n) {printf("%.2f\n", L2.x - L1.x); continue;}
sort(a + 1, a + cnt + 1);
a[cnt + 1].x = L2.x;
db ans = max(0.00, a[1].x - L1.x);
int st = 0; //模仿栈操作
for(int i = 1; i <= cnt; ++i)
{
st += a[i].flg;
if(!st) ans = max(ans, a[i + 1].x - a[i].x);
}
if(ans == 0) puts("No View");
else printf("%.2f\n", ans);
}
return 0;
}
POJ2074 Line of Sight的更多相关文章
- 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 || 直线相交求交点
原题 给出一个房子(线段)的端点坐标,和一条路的两端坐标,给出一些障碍物(线段)的两端坐标.问在路上能看到完整房子的最大连续长度是多长. 将障碍物按左端点坐标排序,然后用房子的右端与障碍物的左端连线, ...
随机推荐
- 使用Docker镜像部署ELK日志系统
使用Docker部署elasticsearch.logstash.kibana 指定版本:6.7.1 (建议使用同一的版本.屏蔽三个软件间的不兼容性) 下载镜像: docker pull elasti ...
- 【7】.net WebAPI Owin OAuth 2.0 密码模式验证实例
1.OAuth密码模式 2.在VS中创建WebAPI项目 在nuget中安装: Microsoft.AspNet.WebApi.Owin Microsoft.Owin.Host.SystemWeb 这 ...
- MVC中学到的小知识(MVC中的跳转,传参)
1.mvc中视图中的href="XXX",这个XXX是控制器地址,不是另一个视图.(这里的href语句只能转向控制器,不能直接转向视图),如果要实现转向视图,可以先转到控制器,然后 ...
- vim 编辑器常规操作
所看视频教程:兄弟连Linux云计算视频教程5.1文本编辑器Vim-5.2 插入命令 a:在光标所在字符后插入; A:在光标所在行尾插入; i:在光标所在字符前插入; I:在光标所在字符行行首插入; ...
- Springboot简介01
前言: spring是近几年java中最具有代表而且最为流行的框架,spring是基于aop和IOC的思想,在我们的项目中充当了一个粘合剂的作用,既可以成为对象工厂,来管理我们的controller. ...
- 【SPOJ】MGLAR10 - Growing Strings
Gene and Gina have a particular kind of farm. Instead of growing animals and vegetables, as it is us ...
- JavaWeb学习总结(八):HttpServletRequest对象
一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...
- html技巧
1.防止盒子透出的解决办法 overflow:hidden:float不为none:display:inline-block: position不为static&relative ...
- Spring Data MongoDB 查询指定字段
DBObject dbObject = new BasicDBObject(); //dbObject.put("name", "zhangsan"); //查 ...
- 网络测速 php代码
<?php /*=====http://hi.csdn.net/yinyiniao=====*/ $fp=fopen("cs.txt","w"); for ...