POJ2074:Line of Sight——题解

http://poj.org/problem?id=2074

题目大意:(下面的线段都与x轴平行)给两条线段,一个点在其中一条线段看另一条线段,但是中间有很多线段阻挡视线。求在线段上最大连续区间使得在上面的点都能看见另一条线段。

——————————————

题解先割了,明天补上。

#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
typedef double dl;
const int INF=2147483647;
const int N=201;
struct point{//既是向量又是点
    dl x;
    dl y;
};
struct line{
    dl x1;
    dl x2;
    dl y;
}p[N],st,ed;
bool cmp(line a,line b){
    return (a.x1<b.x1||(a.x1==b.x1&&a.x2<b.x2)||(a.x1==b.x1&&a.x2==b.x2&&a.y<b.y));
}
inline point getmag(point a,point b){
    point s;
    s.x=b.x-a.x;s.y=b.y-a.y;
    return s;
}
inline int multiX(point a,point b){
    return a.x*b.y-b.x*a.y;
}
inline bool check(point a,point b,point c,point d){
    dl d1=multiX(getmag(c,d),getmag(c,a))*multiX(getmag(c,d),getmag(c,b));
    dl d2=multiX(getmag(a,b),getmag(a,c))*multiX(getmag(a,b),getmag(a,d));
    if(d1<=0&&d2<=0)return 1;
    return 0;
}
inline point intersection(point a,point b,point c,point d){
    point s;
    dl a1=a.y-b.y,b1=b.x-a.x,c1=a.x*b.y-b.x*a.y;
    dl a2=c.y-d.y,b2=d.x-c.x,c2=c.x*d.y-d.x*c.y;
    s.x=(c1*b2-c2*b1)/(a2*b1-a1*b2);
    s.y=(a2*c1-a1*c2)/(a1*b2-a2*b1);
    return s;
}
int n;
int main(){
    while(scanf("%lf%lf%lf",&st.x1,&st.x2,&st.y)!=EOF&&st.x1+st.x2+st.y!=0){
    scanf("%lf%lf%lf",&ed.x1,&ed.x2,&ed.y);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lf%lf%lf",&p[i].x1,&p[i].x2,&p[i].y);
    sort(p+1,p+n+1,cmp);
    double maxn=0,l=0,r=0;
    bool f=0;
    for(int i=n;i>=1;i--){
        if(p[i].y>st.y||p[i].y<ed.y)continue;
        n=i;
        break;
    }
    for(int i=1;i<=n+1;i++){
        if(p[i].y>st.y||p[i].y<ed.y)continue;
        if(!f){
        l=ed.x1;
        f=1;
        }
        else{
        point a,b,c,d;
        a.x=ed.x1;a.y=ed.y;
        b.x=ed.x2;b.y=ed.y;
        c.x=st.x1;c.y=st.y;
        d.x=p[i-1].x2;d.y=p[i-1].y;
        for(int j=1;j<=n;j++){
            if(p[j].y>st.y||p[j].y<ed.y)continue;
            if(i-1==j)continue;
            point e,f;
            e.x=p[j].x1;e.y=p[j].y;
            f.x=p[j].x2;f.y=p[j].y;
            if(check(c,d,e,f)){
            point k=intersection(c,d,e,f);
            if(k.x==e.x&&k.y==e.y)continue;
            d=f;
            }
        }
        l=intersection(a,b,c,d).x;
        }
        if(i==n+1)r=ed.x2;
        else{
        point a,b,c,d;
        a.x=ed.x1;a.y=ed.y;
        b.x=ed.x2;b.y=ed.y;
        c.x=st.x2;c.y=st.y;
        d.x=p[i].x1;d.y=p[i].y;
        for(int j=1;j<=n;j++){
            if(p[j].y>st.y||p[j].y<ed.y)continue;
            if(i-1==j)continue;
            point e,f;
            e.x=p[j].x1;e.y=p[j].y;
            f.x=p[j].x2;f.y=p[j].y;
            if(check(c,d,e,f)){
            point k=intersection(c,d,e,f);
            if(k.x==f.x&&k.y==f.y)continue;
            d=e;
            }
        }
        r=intersection(a,b,c,d).x;
        }
        if(l<r){
        if(l<ed.x1)l=ed.x1;
        if(r>ed.x2)r=ed.x2;
        maxn=max(maxn,r-l);
        }
    }
    if(maxn==0){
        puts("No View");
    }else{
        printf("%.2f\n",maxn);
    }
    }
    return 0;
}
时间: 2024-10-14 16:43:55

POJ2074:Line of Sight——题解的相关文章

poj2074 Line of Sight

计算几何题目,特别要注意障碍物位于House Line上方或者Property Line下方时要首先排除. http://poj.org/problem?id=2074 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 6 using namespace std; 7 const int maxn = 1e6; 8 9 double Hx1

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

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

简单几何(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

POJ 2074 Line of Sight 计算几何

题意: 给出房子,障碍物,观光线(都为平行于x轴的线段).问在观光线上能看到整个房子的最长距离 分析: 将房屋的端点与障碍物的端点连线,求出与观光线的横坐标.这些坐标会把观光线分成多个区间,然后枚举每一个区间的中点,来判断这个区间是否能看到整个房子 要注意的是:不一定每个障碍物都在房屋与观光线之间,与房屋或观光线在同一条直线的可以忽略掉 如果你用的G++,double输出格式为%f #include <iostream> #include <cstdio> #include <

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

原题 给出一个房子(线段)的端点坐标,和一条路的两端坐标,给出一些障碍物(线段)的两端坐标.问在路上能看到完整房子的最大连续长度是多长. 将障碍物按左端点坐标排序,然后用房子的右端与障碍物的左端连线,房子的左端和前一障碍物的右端比较,得出在道路上的能看到的长度取Max即可 #include<cstdio> #include<algorithm> using namespace std; double a,b,c,l,lmx,ans; int n,pos; struct point

Line of Sight 计算几何基础

题意: 题目链接 在房屋与property line之间有障碍物(房屋,property line,障碍物均可看做与x轴平行的线段) 求从房屋到property line最长的能看到的一段的长度 思路: 能看到的一段的长度本身并不好求解 但是不能看到的一段的长度却相对好求解 于是找到property line上看不见的每一段 而后按照左端点排序,乱搞即可 注意事项: 障碍物不一定在property line与房屋之间 可能没有障碍物 边界情况 code: #include<cstdio> #i

USACO 6.5 Closed Fences

Closed Fences A closed fence in the plane is a set of non-crossing, connected line segments with N corners (3 < N < 200). The corners or vertices are each distinct and are listed in counter-clockwise order in an array {xi, yi}, i in (1..N). Every pa

gis制作高程、坡度、坡向分析图&#160;

ArcGIS教程之DEM(高程)的应用(坡度坡向.提等高线) 相关教程:           DEM水文分析(一)           Arcgis下DEM水文分析(二) DEM的应用包括:坡度:Slope.坡向:Aspect.提取等高线.算地形表面的阴影图.可视性分析.地形剖面.水文分析等,其中涉及的知识点有: a)掌握根据DEM 计算坡度.坡向的方法.     b)理解基于DEM数据进行水文分析的基本原理.     c)利用ArcGIS的提供的水文分析工具进行水文分析的基本方法和步骤. 第一

如何制作坡度分析图

ArcGIS教程之DEM(高程)的应用(坡度坡向.提等高线) 相关教程:           DEM水文分析(一)           Arcgis下DEM水文分析(二) DEM的应用包括:坡度:Slope.坡向:Aspect.提取等高线.算地形表面的阴影图.可视性分析.地形剖面.水文分析等,其中涉及的知识点有: a)掌握根据DEM 计算坡度.坡向的方法.     b)理解基于DEM数据进行水文分析的基本原理.     c)利用ArcGIS的提供的水文分析工具进行水文分析的基本方法和步骤. 第一