Line of Sight 计算几何基础

题意:

题目链接
在房屋与property line之间有障碍物(房屋,property line,障碍物均可看做与x轴平行的线段)
求从房屋到property line最长的能看到的一段的长度

思路:

能看到的一段的长度本身并不好求解
但是不能看到的一段的长度却相对好求解
于是找到property line上看不见的每一段
而后按照左端点排序,乱搞即可

注意事项:

  • 障碍物不一定在property line与房屋之间
  • 可能没有障碍物
  • 边界情况

    code:

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=5e4+5;
const double eps=1e-7;
struct sec{double l,r;}a[N];
bool operator<(sec x,sec y){return x.l<y.l;}
struct point{double x,y;};
point e1=(point){0,0},e2=(point){50,0};
double ans;
point operator-(point x,point y){return (point){x.x-y.x,x.y-y.y};}
double operator^(point x,point y){return x.x*y.y-x.y*y.x;}
struct seg{point u,v;}hs,pro;
inline double inc(point p1,point p2)
{
    double s1=(e1-p1)^(e2-p1),s2=(e2-p2)^(e1-p2);
    return p2.x+(p1.x-p2.x)*s2/(s1+s2);
}
int main()
{
    while(7)
    {
        ans=0;
        scanf("%lf%lf%lf",&hs.u.x,&hs.v.x,&hs.u.y);
        hs.v.y=hs.u.y;
        if(hs.u.x<eps&&hs.v.x<eps&&hs.u.y<eps)break;
        scanf("%lf%lf%lf",&pro.u.x,&pro.v.x,&pro.u.y);
        pro.v.y=pro.u.y;e1.y=e2.y=pro.u.y;
        int num=0,cnt=0;scanf("%d",&num);
        for(int i=1;i<=num;++i)
        {
            double x1=0,x2=0,y=0;
            scanf("%lf%lf%lf",&x1,&x2,&y);
            if(y-hs.u.y>-eps||pro.u.y-y>-eps)continue;
            a[++cnt].l=inc(hs.u,(point){x2,y});
            a[cnt].l=min(pro.v.x,max(pro.u.x,a[cnt].l));
            a[cnt].r=inc(hs.v,(point){x1,y});
            a[cnt].r=min(pro.v.x,max(pro.u.x,a[cnt].r));
            swap(a[cnt].l,a[cnt].r);
        }
        if(!cnt){printf("%.2f\n",pro.v.x-pro.u.x);continue;}
        sort(a+1,a+cnt+1);
        double ll=-1,rr=-1;
        for(int i=1;i<=cnt;++i)
        {
            if(ll<-eps&&rr<-eps)
            {
                ll=a[i].l,rr=a[i].r;
                ans=max(ans,ll-pro.u.x);
                continue;
            }
            if(rr-a[i].l>-eps)rr=max(rr,a[i].r);
            else
            {
                ans=max(ans,a[i].l-rr);
                ll=a[i].l,rr=a[i].r;
            }
        }
        ans=max(ans,pro.v.x-rr);
        if(ans<eps)puts("No View");
        else printf("%.2f\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/zmyzmy/p/12220847.html

时间: 2024-10-14 16:43:58

Line of Sight 计算几何基础的相关文章

Line of Sight POJ - 2074 (线段覆盖 )

Line of Sight POJ - 2074 题目链接:https://vjudge.net/problem/POJ-2074 题意:有房子属性线和障碍物,要求你通过属性线能够看到完整房子的最大属性上的距离 思路: 其实将房子右端点和障碍物左端连线,房子左端点和障碍物右端点连线在属性线上的投影部分就是看不到房子的区域,即图中地下红色部分,那么所求就是途中属性线剩下的蓝色大括号,求其最大值,求解过程中还要注意线段的合并,如果没有障碍物那么就输出属性线的长度就行,如果有一个投影线段完全覆盖了属性

nyis oj 68 三点顺序 (计算几何基础)

三点顺序 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描写叙述 如今给你不共线的三个点A,B,C的坐标,它们一定能组成一个三角形,如今让你推断A,B,C是顺时针给出的还是逆时针给出的? 如: 图1:顺时针给出 图2:逆时针给出 <图1>                   <图2> 输入 每行是一组測试数据,有6个整数x1,y1,x2,y2,x3,y3分别表示A,B,C三个点的横纵坐标.(坐标值都在0到10000之间) 输入0 0 0 0 0 0表示输入

计算几何基础——【点积和叉积的用处】

计算几何是算法竞赛的一大块,而叉积是计算机和的基础. 首先叉积是计算说向量之间的叉积,那么我们可以这样定义向量,以及向量的运算符重载. struct Point { double x,y; Point(double x=0,double y=0):x(x),y(y) {} }; typedef Point Vector; Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); } Vector operato

知识点 - 计算几何基础

知识点 - 计算几何基础 讲义 点 我们把点 \(\mathbf r\) 看成从 \(\mathbf 0\) 到 \(\mathbf r\)的向量 \(\vec{\mathbf r}\) #define ftype long double struct point2d { ftype x, y; point2d() {} point2d(ftype x, ftype y): x(x), y(y) {} point2d& operator+=(const point2d &t) { x +=

【kuangbin专题】计算几何基础(极角相关)

[POJ 1696] Space Ants [题目大意] 给定多个点,对他们按照下面的规则排序,每个都在前一个点组成的左边,并且连线不相交(典型如图) [题目分析] 不断进行极角排序,不断选取一定区域内最符合要求的解 [代码] 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define ll double 5 using namespace std; 6 const double eps

BZOJ_1610_[Usaco2008_Feb]_Line连线游戏_(计算几何基础+暴力)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1610 给出n个点,问两两确定的直线中,斜率不同的共有多少条. 分析 暴力枚举直线,算出来斜率放在k数组里面(斜率不存在记为INF),然后去个重统计个数就行了. 其实特水... 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=200+5; 5 const double eps=1e-8,INF=0x7f

简单几何(WA中) POJ 2074 Line of Sight

题目传送门 题意: 分析: /************************************************ * Author :Running_Time * Created Time :2015/11/2 星期一 20:33:38 * File Name :POJ_2074.cpp ************************************************/ #include <cstdio> #include <algorithm> #i

计算几何基础

记录点滴. 1 /* 2 2015.6 HT 3 ACM Work_8 4 5 */ 6 7 #include <iostream> 8 #include <cstdio> 9 using namespace std; 10 11 /* 12 线段判交--ACM 13 14 1.快速排斥实验 15 设以线段P1P2和线段Q1Q2为对角线的矩形为M,N;若M,N 不相交,则两个线段显然不相交: 16 2.跨立实验 17 如果两线段相交,则两线段必然相互跨立对方.若P1P2跨立Q1Q2

POJ_1269_Intersecting_Lines_(计算几何基础)

描述 http://poj.org/problem?id=1269 给出两条直线,判断它们是平行,重合,还是相交,如果相交,求出交点. 分析 比较裸的一道题.学习了直线的写法(参数方程) 1 #include <cstdio> 2 #include <cmath> 3 using namespace std; 4 5 const double eps=1e-8; 6 7 struct pt{ double x,y; pt(double x=0,double y=0):x(x),y(