poj 2074 Line of Sight(视线问题,求直线与线段的交点及判断相交)

来源:互联网 发布:单片机多功能调试 编辑:程序博客网 时间:2024/05/16 14:47
Line of Sight
Time Limit: 1000MS Memory Limit: 30000KTotal Submissions: 2634 Accepted: 813

Description

An architect is very proud of his new home and wants to be sure it can be seen by people passing by his property line along the street. The property contains various trees, shrubs, hedges, and other obstructions that may block the view. For the purpose of this problem, model the house, property line, and obstructions as straight lines parallel to the x axis: 

To satisfy the architect's need to know how visible the house is, you must write a program that accepts as input the locations of the house, property line, and surrounding obstructions and calculates the longest continuous portion of the property line from which the entire house can be seen, with no part blocked by any obstruction.

Input

Because each object is a line, it is represented in the input file with a left and right x coordinate followed by a single y coordinate: 
< x1 > < x2 > < y > 
Where x1, x2, and y are non-negative real numbers. x1 < x2 
An input file can describe the architecture and landscape of multiple houses. For each house, the first line will have the coordinates of the house. The second line will contain the coordinates of the property line. The third line will have a single integer that represents the number of obstructions, and the following lines will have the coordinates of the obstructions, one per line. 
Following the final house, a line "0 0 0" will end the file. 
For each house, the house will be above the property line (house y > property line y). No obstruction will overlap with the house or property line, e.g. if obstacle y = house y, you are guaranteed the entire range obstacle[x1, x2] does not intersect with house[x1, x2].

Output

For each house, your program should print a line containing the length of the longest continuous segment of the property line from which the entire house can be to a precision of 2 decimal places. If there is no section of the property line where the entire house can be seen, print "No View".

Sample Input

2 6 60 15 031 2 13 4 112 13 11 5 50 10 010 15 10 0 0

Sample Output

8.80No View

Source

Mid-Atlantic 2004
题目:http://poj.org/problem?id=2074
题意:给你两条平行线段,以及其他平行于这两条线的线段,求从第二条线段能看到整条第一条线段的连续区间长度的最大值
分析:这题其实还算挺简单的,把所有在两条平行线之间的线段分为两个点,记录是开始节点还算结束节点,然后按x轴大小排序,每次如果两个相邻的点满足,小的那个是结束端点,大的那个是开始端点,就将小的点与房子左端连线,大的和右端,求两条线段在边界线上的交点,然后求交点的距离即可,当然之间很多细节了
PS:这题写了一早上未果,然后下午郁闷的查了一个不懂的单词,才发现理解错题意了,那样理解巨难啊T_T
改正后还没去掉不在平行线之间的线段,wa了一次,偷看discuss时发现的

代码:
#include<cmath>#include<cstdio>#include<iostream>#include<algorithm>using namespace std;const int mm=1111;typedef double mType;struct Tpoint{    mType x,y;    Tpoint(){}    Tpoint(mType _x,mType _y):x(_x),y(_y){}};struct Tsegment{    Tpoint s,t;    Tsegment(){}    Tsegment(Tpoint _s,Tpoint _t):s(_s),t(_t){}    Tsegment(mType sx,mType sy,mType tx,mType ty):s(Tpoint(sx,sy)),t(Tpoint(tx,ty)){}};struct node{    Tpoint s;    bool flag;};struct Tline{    mType A,B,C;    Tline(){}    Tline(Tpoint s,Tpoint t)    {        A=s.y-t.y;        B=t.x-s.x;        C=s.x*t.y-s.y*t.x;    }    Tpoint IntersectPoint(Tline P)    {        mType tmp=P.B*A-P.A*B;        return Tpoint((P.C*B-P.B*C)/tmp,(P.A*C-P.C*A)/tmp);    }};Tpoint MakeVector(Tpoint P,Tpoint Q){    return Tpoint(Q.x-P.x,Q.y-P.y);}mType CrossProduct(Tpoint P,Tpoint Q){    return P.x*Q.y-P.y*Q.x;}mType MultiCross(Tpoint P,Tpoint Q,Tpoint R){    return CrossProduct(MakeVector(Q,P),MakeVector(Q,R));}mType IsLineIntersect(Tsegment P,Tsegment Q){    return MultiCross(P.t,P.s,Q.s)*MultiCross(P.t,P.s,Q.t);}bool cmp(node P,node Q){    return P.s.x<Q.s.x||(P.s.x==Q.s.x&&P.s.y<Q.s.y);}mType sx,tx,wy,maxx,minx,ans;Tsegment seg[mm];node g[mm];mType lx,rx;int i,n,m;mType see(Tsegment P){    if(fabs(P.s.y-P.t.y)<1e-8)return -1;    if(IsLineIntersect(P,seg[0])>0)return -1;    for(int i=1;i<=n;++i)        if(IsLineIntersect(P,seg[i])<0)return -1;    Tline L=Tline(P.s,P.t);    return (-L.C-L.B*seg[n+1].s.y)/L.A;}int main(){    while(scanf("%lf%lf%lf",&sx,&tx,&wy),sx+tx+wy>0)    {        seg[0]=Tsegment(sx,wy,tx,wy);        scanf("%lf%lf%lf%d",&sx,&tx,&wy,&n);        seg[n+1]=Tsegment(sx,wy,tx,wy);        m=0;        for(i=1;i<=n;++i)        {            scanf("%lf%lf%lf",&sx,&tx,&wy);            if(wy<=seg[0].s.y&&wy>=seg[n+1].s.y)                seg[++m]=Tsegment(sx,wy,tx,wy);        }        seg[m+1]=seg[n+1];        n=m;        for(m=0,i=1;i<=n;++i)        {            g[m].s=seg[i].s,g[m++].flag=0;            g[m].s=seg[i].t,g[m++].flag=1;        }        g[m].s=seg[n+1].s;        g[m++].flag=1;        g[m].s=seg[n+1].t;        g[m++].flag=0;        sort(g,g+m,cmp);        ans=-1;        for(i=1;i<m;++i)            if(g[i-1].flag&&!g[i].flag)            {                lx=see(Tsegment(seg[0].s,g[i-1].s));                rx=see(Tsegment(seg[0].t,g[i].s));                if(lx>=0&&rx>=0&&lx<rx)                    ans=max(ans,rx-lx);            }        if(ans<0)puts("No View");        else printf("%.2lf\n",ans);    }    return 0;}


原创粉丝点击