zoukankan      html  css  js  c++  java
  • LA4127计算几何+离散化+点覆盖

      1 /*
      2 LA4127计算几何
      3 离散化的思想。刘的书上已经说得很清楚。
      4 重点是自己手写的函数:
      5 1、判断线段和线段的交点
      6 2、覆盖在最上面的线段的判断
      7 离散化的思想和之前做的LA2527是一致的
      8 */
      9 #include <stdio.h>
     10 #include <stdlib.h>
     11 #include <string.h>
     12 #include <math.h>
     13 #include <ctype.h>
     14 #include <string>
     15 #include <iostream>
     16 #include <sstream>
     17 #include <vector>
     18 #include <queue>
     19 #include <stack>
     20 #include <map>
     21 #include <list>
     22 #include <set>
     23 #include <algorithm>
     24 #define INF 0x3f3f3f3f
     25 #define eps 1e-7
     26 #define eps2 1e-3
     27 #define zero(x) (((x)>0?(x):-(x))<eps)
     28 using namespace std;
     29 
     30 
     31 struct Point
     32 {
     33     double x,y;
     34     Point() {}
     35     Point(double xx,double yy)
     36     {
     37         x=xx;
     38         y=yy;
     39     }
     40     bool operator<(const Point& p) const{
     41         if (x==p.x) return y<p.y;
     42         else return x<p.x;
     43     }
     44 };
     45 
     46 typedef Point Vector;
     47 
     48 struct Segment
     49 {
     50     Point p1,p2;
     51     Segment(){}
     52     Segment(Point p11,Point p22)
     53     {
     54         p1=p11;p2=p22;
     55     }
     56     double getk()
     57     {
     58         return (p1.y-p2.y)/(p1.x-p2.x);
     59     }
     60 }Seg[25005];
     61 
     62 struct Line
     63 {
     64     Point p;
     65     Vector v;
     66     Line(){}
     67     Line(Point pp,Vector vv)
     68     {
     69         v=vv;
     70         p=pp;
     71     }
     72 };
     73 bool operator==(Point A,Point B)
     74 {
     75     if ((fabs(A.x-B.x)<eps) && (fabs(A.y-B.y)<eps)) return true;
     76     else return false;
     77 }
     78 Vector operator-(Point A,Point B)//表示A指向B
     79 {
     80     return Vector(A.x-B.x,A.y-B.y);
     81 }
     82 Vector operator*(Vector A,double k)
     83 {
     84     return Vector(A.x*k,A.y*k);
     85 }
     86 Vector operator+(Point A,Point B)//表示A指向B
     87 {
     88     return Vector(B.x+A.x,B.y+A.y);
     89 }
     90 double Dot(Vector A,Vector B)
     91 {
     92     return A.x*B.x+A.y*B.y;
     93 }
     94 double Length(Vector A)
     95 {
     96     return sqrt(Dot(A,A));
     97 }
     98 double Cross(Vector A,Vector B)
     99 {
    100     return A.x*B.y-A.y*B.x;
    101 }
    102 double Area2(Point A,Point B,Point C)
    103 {
    104     return Cross(B-A,C-A);
    105 }
    106 int dcmp(double x)
    107 {
    108     if(fabs(x)<eps) return 0;
    109     else if(x>0) return 1;
    110     else return -1;
    111 }
    112 double angle(Vector v)
    113 {
    114     return atan2(v.y,v.x);
    115 }
    116 Vector Rotate(Vector A,double rad)//向量向逆时针旋转
    117 {
    118     return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
    119 }
    120 Point InterSection(Line L1,Line L2)//求直线交点
    121 {
    122     Vector u=L1.p-L2.p;
    123     double t=Cross(L2.v,u)/Cross(L1.v,L2.v);
    124     return L1.p+L1.v*t;
    125 }
    126 bool SegInter(Segment l1,Segment l2,double* xx)
    127 {
    128     Point jiao=(InterSection(Line(l1.p1,l1.p2-l1.p1),Line(l2.p1,l2.p2-l2.p1)));
    129     *xx=jiao.x;
    130     if ( *xx-l1.p1.x>=0 && l1.p2.x-*xx>=0 && *xx-l2.p1.x>=0 && l2.p2.x-*xx>=0) return true;else return false;
    131 }
    132 int findUpesetLine(int cnt,double a)//线段个数,中点横坐标,返回最上(后)覆盖这个点的线段序号
    133 {
    134     int ans=-1;
    135     double my=-1;
    136     for(int i=0;i<cnt;i++)
    137     {
    138         double x1=Seg[i].p1.x,y1=Seg[i].p1.y,x2=Seg[i].p2.x,y2=Seg[i].p2.y;
    139         if (x1-a>0 || a-x2>0) continue;
    140         double k1=x1-a,k2=x2-a;
    141         double y=(k2*y1-k1*y2)/(-k1+k2);
    142         if (y-my>0)
    143         {
    144             my=y;
    145             ans=i;
    146         }
    147     }
    148     return ans;
    149 }
    150 int n,cas=0;
    151 double x,h,b;
    152 double X[25500];//离散的x坐标
    153 int main()
    154 {
    155     double ans=0;
    156     int cnt=0;//线段的个数
    157     int cnt2=0;//离散点的个数
    158     while(cin>>n && n>0)
    159     {
    160         cas++;
    161         ans=0;
    162         cnt=cnt2=0;
    163         for(int i=0;i<n;i++)//预处理
    164         {
    165             cin>>x>>h>>b;
    166             b=b/2;
    167             Seg[cnt++]=Segment(Point(x-b,0),Point(x,h));
    168             Seg[cnt++]=Segment(Point(x,h),Point(x+b,0));
    169             X[cnt2++]=x-b;X[cnt2++]=x;X[cnt2++]=x+b;
    170         }
    171         for(int i=1;i<cnt;i++)
    172         for(int j=0;j<i;j++)//线段两两求交点
    173         {
    174             double xx;
    175             bool ok=SegInter(Seg[i],Seg[j],&xx);
    176             if (ok) X[cnt2++]=xx;
    177         }
    178         sort(X,X+cnt2);
    179 //        for(int i=0;i<cnt2;i++) cout<<X[i]<<" ";cout<<endl;
    180         for(int i=0;i<cnt2-1;i++)//枚举每两个相邻离散线段的中点
    181         {
    182             double px=(X[i]+X[i+1])/2;
    183             int num=findUpesetLine(cnt,px);
    184             if (num!=-1){
    185                 double k=Seg[num].getk();//用斜率求线段长度
    186                 ans+=(X[i+1]-X[i])*sqrt(1+k*k);
    187             }
    188         }
    189         printf("Case %d: %d
    
    ",cas,(int)(ans+0.5));
    190     }
    191 
    192 }
  • 相关阅读:
    SQL SERVER常用的统计用法
    SQL SERVER将多行数据合并成一行(转载)
    RabbitMQ安装与搭建
    CentOS 配置vncserver
    sql server2008禁用远程连接
    CentOS系统常用命令
    CentOS系统配置redis
    CentOS系统配置solr
    利用Warensoft Stock Service编写高频交易软件--客户端驱动接口说明
    蛙人高频交易拆单策略—蛙人高频软件结构及使用说明
  • 原文地址:https://www.cnblogs.com/little-w/p/3573373.html
Copyright © 2011-2022 走看看