嘟嘟嘟




题意:用一条水平线段表示以栋房子:\((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的更多相关文章

  1. Poj 2074 Line of Sight

    地址:http://poj.org/problem?id=2074 题目: Line of Sight Time Limit: 1000MS   Memory Limit: 30000K Total ...

  2. unity下的Line of Sight(LOS)的绘制

    先说说什么是Linf of Sight.在很多RTS游戏中,单位与单位之间的视野关系经常会受到障碍物遮挡.Line of Sight指的就是两个物体之间是否没有障碍物遮挡. 比如在dota中,玩家的视 ...

  3. 【转】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é ...

  4. 【转】unity下的Line of Sight(LOS)的绘制

    http://www.cnblogs.com/yangrouchuan/p/6366629.html 先说说什么是Linf of Sight.在很多RTS游戏中,单位与单位之间的视野关系经常会受到障碍 ...

  5. POJ2074:Line of Sight——题解

    http://poj.org/problem?id=2074 题目大意:(下面的线段都与x轴平行)给两条线段,一个点在其中一条线段看另一条线段,但是中间有很多线段阻挡视线.求在线段上最大连续区间使得在 ...

  6. 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 ...

  7. 简单几何(直线求交点) POJ 2074 Line of Sight

    题目传送门 题意:从一条马路(线段)看对面的房子(线段),问连续的能看到房子全部的最长区间 分析:自己的思路WA了:先对障碍物根据坐标排序,然后在相邻的障碍物的间隔找到区间,这样还要判断是否被其他障碍 ...

  8. poj 2074 Line of Sight 计算几何

    /** 大意:给定一个建筑--水平放置,给定n个障碍物, 给定一条街道,从街道上能看到整个建筑的最长的连续的区域 思路: 分别确定每一个障碍物所确立的盲区,即----建筑物的终点与障碍物的起点的连线, ...

  9. [poj] 2074 Line of Sight || 直线相交求交点

    原题 给出一个房子(线段)的端点坐标,和一条路的两端坐标,给出一些障碍物(线段)的两端坐标.问在路上能看到完整房子的最大连续长度是多长. 将障碍物按左端点坐标排序,然后用房子的右端与障碍物的左端连线, ...

随机推荐

  1. 来一波Linux中查看cpu、磁盘、内存、网络的命令

    转载请注明出处. 如果想远程管理服务器就有远程管理卡,比如Dell idRAC,HP ILO,IBM IMM 查看硬件的温度/风扇转速,电脑有撸大师,服务器就有ipmitool.使用ipmitool实 ...

  2. Mongodb操作之查询(循序渐进对比SQL语句)(转http://www.tuicool.com/articles/UzQj6rF)

    工具推荐:Robomongo,可自行百度寻找下载源,个人比较推荐这个工具,相比较mongoVUE则更加灵活. 集合简单查询方法 mongodb语法:db.collection.find()  //co ...

  3. C# 文件上传 制作水印

    其实C#的文件上传是非常简单的 前台代码 <asp:FileUpload ID="FileUpload1" accept=".jpg,.png,.jpeg" ...

  4. 六、阻塞队列LinkedBlockQueue

    一.简介 Java提供了FIFO先进先出的阻塞队列实现,这其实是一种生产者消费者理念,可以通过阻塞队列将生产者和消费者进行解耦合. LinkedBlockQueue是一种无界队列,但事实上它只是队列可 ...

  5. 11、Map、可变参数、Collections

    Map接口 Map集合概述 *A:Map集合概述: 我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同 a:Collection中的集合,元素 ...

  6. data-id 和 id 的区别

    作者:Zeropoint零点 来源:CSDN 原文:https://blog.csdn.net/qq_41648132/article/details/80364335 版权声明:本文为Zeropoi ...

  7. python中字符串格式化%与.format

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  8. 1739 GPA排序 个人博客:doubleq.win

    个人博客:doubleq.win 1739 GPA排序  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 青铜 Bronze 题解       题目描述 Description ...

  9. 【Win32】对指定进程进行禁音

    使用例子如下: CAudioMgr AudioMgr; AudioMgr.SetProcessMute(GetCurrentProcessId()); H文件的内容如下: #pragma once # ...

  10. CentOS7运维管理笔记(12)----修改主机名

    CentOS修改主机名 CentOS7和CentOS6.5 修改主机名的方法略有不同. 通过 hostname 命令可以查看当前的主机名. 1. 临时修改主机名 通过 'hostname 新的主机名' ...