题意
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 }