poj 2074

这是一道基础几何题,不过久久WA也不知道为什么,参照了http://blog.csdn.net/non_cease/article/details/7773307的不过比较奇怪的不知道为什么非要用C++提交才能过,而G++提交却不能过,题目解法大概如下:

1.房屋的左点与障碍的右点连接成线交于观测线得到一个点a,再用房屋的右点与障碍的左点连接交于观测线得到另一点b,那么两点间的距离就是视线被挡住的部分。

2.求出所有障碍的遮挡部分,然后排序,根据分析然后进行一遍比较就好,不过要注意把观测线的两个端点算上,考虑完全就可以解了,这个题好像没有给出具体数据范围所以还是用动态声请吧,不过真心不知道为什么C++能过G++过不了。

#include<cstdio>
#include<algorithm>
#include<math.h>

using namespace std;

const double eps = 1e-10;
const int maxn=1000;

struct Point {
     double x,y;
};

struct Line {
     Point a,b;
     double left,right;
}house,pro;

int dblcmp(double x){
     return x<-eps?-1:x>eps;
}

double getX(Point p1,Point p2, double y){
     return (y-p1.y)*(p1.x-p2.x)/(p1.y-p2.y)+p1.x;
}

bool cmp(Line l1,Line l2){
     return dblcmp(l1.left-l2.left)<=0;
}

int main(){
     double x1,x2,y;
     int n;
     while(1){
         scanf("%lf %lf %lf",&x1,&x2,&y);
         if(!dblcmp(x1)&&!dblcmp(x2)&&!dblcmp(y))break;
         house.a.x=x1, house.b.x=x2, house.a.y=house.b.y=y;
         scanf("%lf %lf %lf",&x1,&x2,&y);
         pro.a.x=x1, pro.b.x=x2, pro.a.y=pro.b.y=y;
         scanf("%d",&n);
         int b_num=0; 
         Line*ob=new Line[n];//没告诉长度就使用动态声请 
         for(int i=0;i<n;i++){
             scanf("%lf %lf %lf",&x1,&x2,&y);
             if(dblcmp(y-house.a.y)>=0||dblcmp(y-pro.a.y)<=0)continue;//不符合的障碍物直接不要算在内,这是个坑 
             ob[b_num].a.x=x1, ob[b_num].b.x=x2;
             ob[b_num].a.y=ob[b_num].b.y=y;
             ob[b_num].left=getX(house.b,ob[b_num].a,pro.a.y);
             ob[b_num].right=getX(house.a,ob[b_num].b,pro.a.y);
             b_num++;
        }
        sort(ob,ob+b_num,cmp);
        double ans=0;
        if(dblcmp(ob[0].left-pro.a.x)>0)ans=ob[0].left-pro.a.x;
        if(dblcmp(ob[0].right-pro.a.x)<0)ob[0].right=pro.a.x;
        int p=0;//表示当前最靠右的点的障碍物下标 
        double tmp; 
        for(int i=1; i<b_num; i++){
              if(dblcmp(ob[p].right-pro.b.x)>=0)break;//当前最靠右点的下标已经完全挡住了游客
              tmp=ob[i].left-ob[p].right;
              if(dblcmp(tmp-ans)>0){
                  i=p;
                  if(dblcmp(tmp-ans)>0)ans=tmp;                     
              } 
              else if(dblcmp(ob[i].right-ob[p].right)>0)p=i;
        }
        tmp=pro.b.x-ob[p].right;
        if(dblcmp(tmp-ans)>0)ans=tmp;//处理最右端视线情况 
        if(dblcmp(ans)>0)printf("%.2lf\n",ans);
        else printf("No View\n"); 
        delete [] ob;//释放养成好习惯 
     }
     return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值