POJ 2074

题目链接:http://poj.org/problem?id=2074

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

题目大意: 求property line上能看到房子全貌的最长段

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

题目思路: 先求出来每条障碍物线遮挡property line的线段,对线段的左端点进行排序。

                    从最左一条开始扫描,考察他前面的所有线段中,右端点最远的一条线段和本线段之间的关系,进行分类讨论

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

题目细节:

1、障碍线可能在house的上面或者与house平行,或者有可能在property的下面或与其平行。

2、在第一条线段左端点的左边和最右的右端点的右边 可能需要计算

3、这题需要用double才能过,且选用c++过不了,需要选g++(木有搞清楚为毛)

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

这题改了好几遍,代码的逻辑不清楚了,凑和着看吧。。

源代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;

typedef double T;

struct Pt
{
   T x;
   T y;
   T len;

   Pt(){}
   Pt(T px,T py)
   {
       x = px;
       y = py;
   }

   Pt &operator +(const Pt &p) const
   {
       Pt c;
       c.x = x + p.x;
       c.y = y + p.y;
       return c;
   }

   Pt &operator -(const Pt &p) const
   {
       Pt c;
       c.x = x - p.x;
       c.y = y - p.y;
       return c;
   }
};

struct Line
{
    Pt a;
    Pt b;
    int cont;

    Line(){}
    Line (Pt p1,Pt p2)
    {
       a = p1;
       b = p2;
    }

};

Line line[10000],house,road,cur;

bool cmp(Line l1,Line l2)
{
    return l1.a.x < l2.a.x;
}

Pt seg(Pt a,Pt b)
{
    T x = 0;

    x = a.x + (b.x - a.x)*(road.a.y - a.y)/(b.y - a.y);

    return Pt(x,road.a.y);
}

double max(double a,double b)
{
    if(a>b) return a;
    else return b;
}

int main()
{
    int i = 0,n = 0,j = 0;
    T x1,x2,y;
    T ans = 0;
    T temp = 0;
    int flag = 0;

    scanf("%lf%lf%lf",&x1,&x2,&y);
    while(x1||x2||y)
    {
        house = Line(Pt(x1,y),Pt(x2,y));
        scanf("%lf%lf%lf",&x1,&x2,&y);
        road = Line(Pt(x1,y),Pt(x2,y));

        if(house.a.y == road.a.y)
        {
           printf("No View\n");
           continue;
        }

        scanf("%d",&n);
        for(i = 0;i<n;i++)
        {
            scanf("%lf%lf%lf",&x1,&x2,&y);
            if(y>=house.a.y || y<=road.a.y)
            {
               n--;
               i--;
               continue;
            }
            cur = Line(Pt(x1,y),Pt(x2,y));
            line[i] = Line(seg(house.b,cur.a),seg(house.a,cur.b));
        }

        sort(line,line+n,cmp);
        ans = 0;

        if(line[0].a.x>road.a.x && n>0)
          ans = line[0].a.x - road.a.x;
        for(i = 1;i<n;i++)
        {
           if(line[i].a.x<=road.a.x) continue;

           temp = road.a.x;
           for(j = 0;j<i;j++)
           {
               if(line[j].b.x > temp) temp = line[j].b.x;
           }

           if(temp>line[i].a.x) continue;
           else
           {
               if(temp>road.b.x) break;
               else if(line[i].a.x>road.b.x)
                   {
                      ans = max(road.b.x - line[i-1].a.x,ans);
                      break;
                   }
                    else ans = max(line[i].a.x-temp,ans);
           }
        }

        if(n == 1)
        {
            double a = 0,b = 0;
            double c = road.b.x - road.a.x;
            if(line[0].a.x>road.a.x) a = line[0].a.x - road.a.x;
            if(line[0].b.x<road.b.x) b = road.b.x - line[0].b.x;
            if(a>c) a = c;
            if(b>c) b = c;
            ans = max(a,b);
        }
        else
        {
            flag = 0;
            for(i = 0;i<n;i++)
            {
               if(line[i].b.x>=road.b.x)
               {
                   flag = 1;
                   break;
               }
            }
            if(!flag) ans = max(road.b.x - line[n-1].b.x,ans);
        }


        if(ans == 0.0)
          printf("No View\n");
        else
          printf("%.2f\n",ans);

        scanf("%lf%lf%lf",&x1,&x2,&y);
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值