Poj.2074 Line of Sight【计算几何-线段】 2015/08/28

Line of Sight
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 3875 Accepted: 1210

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 6
0 15 0
3
1 2 1
3 4 1
12 13 1
1 5 5
0 10 0
1
0 15 1
0 0 0

Sample Output

8.80
No View

Source


注:今天碰到的又一道神题,虽然部分数据没过,但是跟别人的AC代码几乎一样,不管怎么提交全是WA,数组开多大都是WA,最后new一个数组就不明所以的AC了o(╯□╰)o
题意很简单就是求能看到完整房子的最长的一段距离(在 property line上
下面就看看这神一样的代码吧:
//无限WA
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>

using namespace std;

#define eps 1e-8
struct line{
    double sx,ex;
    double y;
}H,P;

struct point{
    double x1,x2,y;
    double start,finish;
}O[1000010];

int dblcmp(double a){
    if( fabs(a) < eps )
        return 0;
    return a > 0 ? 1 : -1;
}

bool cmp(const point& a,const point& b){
    return dblcmp(a.start-b.start) <= 0;
}

double watch(double x,double ex,double y,double ey,double yy){ //障碍物看到完整房子时的临界点
    return (yy-ey)*(ex-x)/(ey-y)+ex;
}

int main(){
    double x1,x2,y;
    int N;
    while( scanf("%lf%lf%lf",&H.sx,&H.ex,&H.y) ){
        if( !dblcmp(H.sx) && !dblcmp(H.ex) && !dblcmp(H.y) )
            break;
        scanf("%lf%lf%lf",&P.sx,&P.ex,&P.y);
        scanf("%d",&N);
        int n = 0;
        for( int i = 0 ; i < N ; ++i ){
            scanf("%lf%lf%lf",&x1,&x2,&y);
            if( dblcmp(y-H.y) >= 0 || dblcmp(y-P.y) <= 0 ) continue;
            O[n].x1 = x1;
            O[n].x2 = x2;
            O[n].y = y;
            O[n].start = watch(O[n].x1,H.ex,y,H.y,P.y);
            O[n].finish = watch(O[n].x2,H.sx,y,H.y,P.y);
            n++;
        }
        sort(O,O+n,cmp);
        double ans = 0,ret;
        int k = 0;
        if( dblcmp(O[0].start-P.sx) > 0 )
            ans = O[0].start - P.sx;
        if( dblcmp(O[0].finish-P.sx) < 0 )
            O[0].finish = P.sx;
        for( int i = 1 ; i < n ; ++i ){
            if( dblcmp(O[k].finish-P.ex) >= 0 ) break;
            ret = O[i].start-O[k].finish;
            if( dblcmp(ret) > 0 ){
                k = i;
                if( dblcmp(ret-ans) > 0 )
                    ans = ret;
            }
            else if( dblcmp(O[i].finish-O[k].finish) > 0 )
                k = i;
        }
        ret = P.ex - O[k].finish;
        if( dblcmp(ret-ans) > 0 )
            ans = ret;
        if( dblcmp(ans) > 0 )
            printf("%.2lf\n",ans);
        else printf("No View\n");
    }
    return 0;
}
<pre name="code" class="cpp">//AC
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>

using namespace std;

#define eps 1e-8
struct line{
    double sx,ex;
    double y;
}H,P;

struct point{
    double x1,x2,y;
    double start,finish;
};

int dblcmp(double a){
    if( fabs(a) < eps )
        return 0;
    return a > 0 ? 1 : -1;
}

bool cmp(const point& a,const point& b){
    return dblcmp(a.start-b.start) <= 0;
}

double watch(double x,double ex,double y,double ey,double yy){ //障碍物看到完整房子时的临界点
    return (yy-ey)*(ex-x)/(ey-y)+ex;
}

int main(){
    double x1,x2,y;
    int N;
    while( scanf("%lf%lf%lf",&H.sx,&H.ex,&H.y) ){
        if( !dblcmp(H.sx) && !dblcmp(H.ex) && !dblcmp(H.y) )
            break;
        scanf("%lf%lf%lf",&P.sx,&P.ex,&P.y);
        scanf("%d",&N);
        point* O = new point[N];
        int n = 0;
        for( int i = 0 ; i < N ; ++i ){
            scanf("%lf%lf%lf",&x1,&x2,&y);
            if( dblcmp(y-H.y) >= 0 || dblcmp(y-P.y) <= 0 ) continue;
            O[n].x1 = x1;
            O[n].x2 = x2;
            O[n].y = y;
            O[n].start = watch(O[n].x1,H.ex,y,H.y,P.y);
            O[n].finish = watch(O[n].x2,H.sx,y,H.y,P.y);
            n++;
        }
        sort(O,O+n,cmp);
        double ans = 0,ret;
        int k = 0;
        if( dblcmp(O[0].start-P.sx) > 0 )
            ans = O[0].start - P.sx;
        if( dblcmp(O[0].finish-P.sx) < 0 )
            O[0].finish = P.sx;
        for( int i = 1 ; i < n ; ++i ){
            if( dblcmp(O[k].finish-P.ex) >= 0 ) break;
            ret = O[i].start-O[k].finish;
            if( dblcmp(ret) > 0 ){
                k = i;
                if( dblcmp(ret-ans) > 0 )
                    ans = ret;
            }
            else if( dblcmp(O[i].finish-O[k].finish) > 0 )
                k = i;
        }
        ret = P.ex - O[k].finish;
        if( dblcmp(ret-ans) > 0 )
            ans = ret;
        if( dblcmp(ans) > 0 )
            printf("%.2lf\n",ans);
        else printf("No View\n");
        delete [] O;
    }
    return 0;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值