zoukankan      html  css  js  c++  java
  • LA 4127

    题目链接

    非原创 原创地址:http://blog.csdn.net/jingqi814/article/details/26117241

    题意:输入n座山的信息(山的横坐标,高度,山底宽度),计算他们的轮廓线,

    即露出来的表面边长,有些山是重叠的不计。空白地带不计,每座山都是等腰三角形。

    分析:大白书P414页。

    求小山的总长度,用一些虚线将其离散化,分成一段一段的,特征点:山脚,山顶,交点。这样就能保

    证相邻两个扫描点之间再无交点。然后一最上面的点就是分割点,维护上一个点lastp即可。

      1 #include<iostream>
      2 #include<cmath>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<vector>
      6 const double eps=1e-8;
      7 using namespace std;
      8 
      9 struct Point{    //定义点
     10     double x;
     11     double y;
     12     Point(double x=0,double y=0):x(x),y(y){}   //构造函数
     13     //void operator<<(Point &A) {cout<<A.x<<' '<<A.y<<endl;}
     14 };
     15 
     16 int dcmp(double x)  {return (x>eps)-(x<-eps); }   //判断精度
     17 
     18 typedef  Point  Vector;    //自定义别名
     19 
     20 Vector  operator +(Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y);} //向量+向量=向量,点+向量=点
     21 
     22 Vector  operator -(Vector A,Vector B) { return Vector(A.x-B.x,A.y-B.y); }  //点-点=向量
     23 
     24 Vector  operator *(Vector A,double p) { return Vector(A.x*p,A.y*p);  }   //向量*数=向量
     25 
     26 Vector  operator /(Vector A,double p) {return Vector(A.x/p,A.y/p);}    //向量/数=向量
     27 
     28 ostream &operator<<(ostream & out,Point & P) { out<<P.x<<' '<<P.y<<endl; return out;}  //输出点的 符号重载
     29 
     30 bool  operator< (const Point &A,const Point &B) { return A.x<B.x||(A.x==B.x&&A.y<B.y); }  //小于号 重载
     31 
     32 bool  operator== ( const Point &A,const Point &B) { return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0;}  //等于号 重载
     33 
     34 double  Dot(Vector A,Vector B) {return A.x*B.x+A.y*B.y;}  //点积
     35 
     36 double  Cross(Vector A,Vector B)  {return A.x*B.y-B.x*A.y; } //叉积
     37 
     38 double  Length(Vector A)  { return sqrt(Dot(A, A));}  //向量长度
     39 
     40 double  Angle(Vector A,Vector B) {return acos(Dot(A,B)/Length(A)/Length(B));}  //向量夹角
     41 
     42 double  Area2(Point A,Point B,Point C ) {return Cross(B-A, C-A);}  //三角形面积
     43 
     44 Vector Rotate(Vector A,double rad) { return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));} //向量旋转,rad为逆时针旋转的弧度
     45 Vector Normal(Vector A) {double L=Length(A);return Vector(-A.y/L,A.x/L);}  //计算向量的单位法线,需确保A不是零向量。
     46 
     47 Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)  //两直线的交点。需确保直线 P+tv 和 Q+tw有唯一交点,cross(v,w)需非0。
     48 {                                                             //t是参数,v,w分别为两直线的向量。
     49     Vector u=P-Q;
     50     double t=Cross(w, u)/Cross(v,w);
     51     return P+v*t;
     52 }
     53 
     54 double DistanceToLine(Point P,Point A,Point B)  //点到直线的距离,p到ab的距离
     55 {
     56     Vector v1=P-A; Vector v2=B-A;
     57     return fabs(Cross(v1,v2))/Length(v2);
     58 }
     59 
     60 double DistanceToSegment(Point P,Point A,Point B)  //点到线段的距离,p到ab
     61 {
     62     if(A==B)  return Length(P-A);
     63     Vector v1=B-A;
     64     Vector v2=P-A;
     65     Vector v3=P-B;
     66 
     67     if(dcmp(Dot(v1,v2))==-1)    return  Length(v2);
     68     else if(Dot(v1,v3)>0)    return Length(v3);
     69     else return DistanceToLine(P, A, B);
     70 
     71 }
     72 
     73 Point GetLineProjection(Point P,Point A,Point B)  //点在直线的投影,p到ab
     74 {
     75     Vector v=B-A;
     76     Vector v1=P-A;
     77     double t=Dot(v,v1)/Dot(v,v);
     78     return  A+v*t;
     79 }
     80 
     81 bool  SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)  //判断线段相交,交点不在端点上(如果交点在端点上可以借助下面的OnSegment来判断)
     82 {
     83     double c1=Cross(b1-a1, a2-a1);
     84     double c2=Cross(b2-a1, a2-a1);
     85     double c3=Cross(a1-b1, b2-b1);
     86     double c4=Cross(a2-b1, b2-b1);
     87     return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0 ;
     88 }
     89 
     90 bool  OnSegment(Point P,Point A,Point B)  //判断一个点是否在一条线段上
     91 {
     92     return dcmp(Cross(P-A, P-B))==0&&dcmp(Dot(P-A,P-B))<0;
     93 }
     94 
     95 double PolygonArea(Point *p,int n)  //多边形的有向面积
     96 {
     97     double area=0;
     98 
     99     for(int i=1;i<n-1;i++)
    100     {
    101         area+=Cross(p[i]-p[0], p[i+1]-p[0]);
    102     }
    103     return area/2;
    104 
    105 }
    106 
    107 Point  read_point()   //输入点
    108 {
    109     Point P;
    110     scanf("%lf%lf",&P.x,&P.y);
    111     return  P;
    112 }
    113 
    114 int n;
    115 Point L[110][2][2];
    116 double x[20000];   //  存放离散化的x坐标
    117 
    118 int main()
    119 {
    120     double X,H,B;
    121     int cas=0;
    122     while(cin>>n && n)
    123     {
    124         int c=0;
    125         for(int i=0;i<n;i++)
    126         {
    127             scanf("%lf%lf%lf",&X,&H,&B);
    128             L[i][0][0]=Point(X-B*0.5,0);
    129             L[i][0][1]=L[i][1][0]=Point(X,H);
    130             L[i][1][1]=Point(X+B*0.5,0);
    131 
    132             x[c++]=X-B*0.5;
    133             x[c++]=X;
    134             x[c++]=X+B*0.5;
    135         }
    136             for(int i=0;i<n;i++)
    137                 for(int a=0;a<2;a++)
    138                     for(int j=i+1;j<n;j++)
    139                         for(int b=0;b<2;b++)
    140                         {
    141                             Point A=L[i][a][0];
    142                             Point B=L[i][a][1];
    143                             Point C=L[j][b][0];
    144                             Point D=L[j][b][1];
    145 
    146                             if(SegmentProperIntersection(A, B, C, D))
    147                             {
    148                                 x[c++]=GetLineIntersection(A, B-A, C, D-C).x;
    149                             }
    150                         }
    151 
    152         sort(x,x+c);
    153         c=unique(x, x+c)-x; //unique()函数去重函数,在头文件algorithm中
    154         double ans=0;
    155         Point lastp=Point(x[0],0);
    156 
    157         for(int i=0;i<c;i++)
    158         {
    159             Point P=Point(x[i],0);
    160             Vector v=Vector(0,1);
    161             double maxy=-1;
    162             Point inter;
    163 
    164             for(int j=0;j<n;j++)
    165                 for(int a=0;a<2;a++)
    166                 {
    167                     Point A=L[j][a][0];
    168                     Point B=L[j][a][1];
    169                     if(dcmp(A.x-x[i])<=0&&dcmp(B.x-x[i])>=0)
    170                     {
    171                         inter=GetLineIntersection(A, B-A, P, v);
    172                         maxy=max(maxy,inter.y);
    173                     }
    174                 }
    175             if(i>0&&(dcmp(maxy)>0||dcmp(lastp.y)>0))   ans+=Length(Point(x[i],maxy)-lastp);
    176             lastp=Point(x[i],maxy);
    177         }
    178         printf("Case %d: %.0f
    
    ",++cas,ans);
    179     }
    180 }
  • 相关阅读:
    大端小端
    浅谈协程
    boost总结之any
    boost总结之variant
    STL总结之functor
    zabbix设置多个收件人
    zabbix设置发送消息的时间
    zabbix利用微信报警
    Windos无法验证文件数组签名
    zabbix基础安装
  • 原文地址:https://www.cnblogs.com/bfshm/p/3870280.html
Copyright © 2011-2022 走看看