zoukankan      html  css  js  c++  java
  • [CERC2016]凸轮廓线

    题意

    https://www.luogu.org/problem/P3680


    思考

    拆点即可。

    注意精度。


    代码

      1 // luogu-judger-enable-o2
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 typedef long double ld;
      5 const ld eps=1E-16;
      6 const ld pi=acos(-1);
      7 const ld inf=1E9;
      8 inline bool equal(ld x,ld y)
      9 {
     10     return abs(x-y)<=eps;
     11 }
     12 struct pt
     13 {
     14     ld x,y;
     15     pt(ld a=0,ld b=0){x=a,y=b;}
     16     pt operator+(const pt&A){return pt(x+A.x,y+A.y);}
     17     pt operator-(const pt&A){return pt(x-A.x,y-A.y);}
     18     pt operator*(ld d){return pt(x*d,y*d);}
     19     pt operator/(ld d){return pt(x/d,y/d);}
     20     ld operator*(const pt&A){return x*A.y-y*A.x;}
     21     void out(){cout<<"("<<x<<","<<y<<")";}
     22 };
     23 struct line
     24 {
     25     pt A,B;
     26     line(pt a=pt(),pt b=pt())
     27     {
     28         A=a,B=b;
     29     }
     30 };
     31 inline int cross(pt A,pt B)
     32 {
     33     ld d=A*B;
     34     if(equal(d,0))
     35         return 0;
     36     return d>0?1:-1;
     37 }
     38 inline ld dis(pt A,pt B)
     39 {
     40     return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
     41 }
     42 inline pt intersection(line a,line b)
     43 {
     44     pt A=b.B-b.A,B=a.B-a.A,C=b.A-a.A;
     45     if(cross(A,B)==0)
     46         return pt(inf,inf);
     47     ld d=-(B*C)/(B*A);
     48     return b.A+A*d;
     49 }
     50 inline pt foot(pt A,line a)
     51 {
     52     return intersection(line(A,A+pt(a.B.y-a.A.y,a.A.x-a.B.x)),a);
     53 }
     54 inline bool seg(line a,line b)
     55 {
     56     return cross(a.A-b.A,b.B-b.A)*cross(a.B-b.A,b.B-b.A)==-1&&
     57            cross(b.A-a.A,a.B-a.A)*cross(b.B-a.A,a.B-a.A)==-1;
     58 }
     59 pt O(0,0);
     60 bool cmp(pt A,pt B)
     61 {
     62     ld x=atan2(A.y-O.y,A.x-O.x),y=atan2(B.y-O.y,B.x-O.x);
     63     if(equal(x,y))
     64         return dis(A,O)<dis(B,O);
     65     return x<y;
     66 }
     67 vector<pt>convex(vector<pt>P)
     68 {
     69     int pos=0;
     70     for(int i=1;i<P.size();++i)
     71         if(P[i].x<P[pos].x)
     72             pos=i;
     73     swap(P[pos],P[0]);
     74     O=P[0];
     75     sort(P.begin()+1,P.end(),cmp);
     76     vector<pt>ans;
     77     int now=0;
     78     for(int i=0;i<P.size();++i)
     79     {
     80         while(now>1&&cross(P[i]-ans[now-2],ans[now-1]-ans[now-2])!=-1)
     81             ans.pop_back(),--now;
     82         ans.push_back(P[i]);
     83         ++now;
     84     }
     85     return ans;
     86 }
     87 inline bool cmpLine(line a,line b)
     88 {
     89     return atan2(a.A.y-a.B.y,a.A.x-a.B.x)<atan2(b.A.y-b.B.y,b.A.x-b.B.x);
     90 }
     91 inline bool onClockwise(line a,line b,line c)//b,c的交点在a顺时针方向 
     92 {
     93     return cross(intersection(b,c)-a.A,a.B-a.A)==1;
     94 }
     95 inline bool isSame(line a,line b)
     96 {
     97     return cross(a.A-b.B,b.A-b.B)==0;
     98 }
     99 line wait[66666];
    100 vector<line>halfPlane(vector<line>A)
    101 {
    102     vector<line>ans;
    103     sort(A.begin(),A.end(),cmpLine);
    104     int l=1,r=0;
    105     for(int i=0;i<A.size();++i)
    106     {
    107         while(l<r&&!isSame(A[i],wait[r])&&onClockwise(A[i],wait[r-1],wait[r]))
    108             --r;
    109         while(l<r&&!isSame(A[i],wait[l])&&onClockwise(A[i],wait[l],wait[l+1]))
    110             ++l;
    111         if(!isSame(A[i],wait[r])||r==0)
    112             wait[++r]=A[i];
    113         else if(!onClockwise(wait[r],wait[r-1],A[i]))
    114             wait[r]=A[i];
    115     }
    116     while(l<r&&onClockwise(wait[l],wait[r],wait[r-1]))
    117         --r;
    118     while(l<r&&onClockwise(wait[r],wait[l],wait[l+1]))
    119         ++l;
    120     for(int i=l;i<=r;++i)
    121         ans.push_back(wait[i]);
    122     return ans;
    123 }
    124 inline ld length(vector<pt>P)
    125 {
    126     ld sum=0;
    127     for(int i=1;i<P.size();++i)
    128         sum+=dis(P[i-1],P[i]);
    129     sum+=dis(P[P.size()-1],P[0]);
    130     return sum;
    131 }
    132 const ld base=10000;
    133 int main()
    134 {
    135     ios::sync_with_stdio(false);
    136     int n;
    137     cin>>n;
    138     vector<pt>P;
    139     for(int i=1;i<=n;++i)
    140     {
    141         char ch;
    142         cin>>ch;
    143         ld x=i;
    144         if(ch=='S')
    145         {
    146             P.push_back(pt(x,0));
    147             P.push_back(pt(x+1,0));
    148             P.push_back(pt(x+1,1));
    149             P.push_back(pt(x,1));
    150         }
    151         else if(ch=='T')
    152         {
    153             P.push_back(pt(x,0));
    154             P.push_back(pt(x+1,0));
    155             P.push_back(pt(x+0.5,sqrt(3)/2));
    156         }
    157         else
    158         {
    159             for(ld j=0;j<base;j+=1)
    160             {
    161                 ld ra=2*pi/base*j;
    162                 P.push_back(pt(x+0.5+cos(ra)/2,0.5+sin(ra)/2));
    163             }
    164         }
    165     }
    166     ld ans=length(convex(P));
    167     cout<<fixed<<setprecision(7)<<ans<<endl;
    168     return 0;
    169 }
    View Code
  • 相关阅读:
    圣杯+双飞翼 自适应布局
    drupal8 用户指南
    运维笔记:zabbix的运用(1)安装过程
    Nginx的初识
    PHP 获取LDAP服务器Schema数据
    Nginx(alias 和 root的区别)
    vue开发--生成token并保存到本地存储中
    PHP程序员必须知道的两种日志
    MVC 应用程序级别捕捉异常
    消息队列MQ
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/11409237.html
Copyright © 2011-2022 走看看