zoukankan      html  css  js  c++  java
  • 【计算几何】【分类讨论】Gym

    注意等边三角形的上顶点是卡不到边界上的。

    于是整个凸包分成三部分:左边的连续的三角形、中间的、右边的连续的三角形。

    套个计算几何板子求个三角形顶点到圆的切线、三角形顶点到正方形左上角距离啥的就行了,分类比较多。

    #include<cstdio>
    #include<cmath>
    using namespace std;
    const double PI=acos(-1.0);
    int n;
    char a[25];
    struct Point{
    	double x,y;
    	double length(){
    		return sqrt(x*x+y*y);
    	}
    };
    typedef Point Vector;
    Vector operator - (const Point &a,const Point &b){
    	return (Vector){a.x-b.x,a.y-b.y};
    }
    Vector operator + (const Vector &a,const Vector &b){
    	return (Vector){a.x+b.x,a.y+b.y};
    }
    Vector operator * (const double &K,const Vector &v){
    	return (Vector){K*v.x,K*v.y};
    }
    Vector Rotate(Vector A,double rad)
    {
    	return (Vector){A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad)};
    }
    Vector unit(Vector A){
    	double l=A.length();
    	return (Vector){A.x/l,A.y/l};
    }
    double sqr(double x){
    	return x*x;
    }
    int main(){
    	scanf("%d%s",&n,a+1);
    	bool alltr=1;
    	for(int i=1;i<=n;++i){
    		if(a[i]!='T'){
    			alltr=0;
    			break;
    		}
    	}
    	if(alltr){
    		printf("%d
    ",2*n+1);
    	}
    	else{
    		double ans=0;
    		int I,J;
    		for(int i=1;i<=n;++i){
    			if(a[i]!='T'){
    				if(i!=1){
    					if(a[i]=='S'){
    						ans+=((Point){0.5,sqrt(3.0)/2.0}-(Point){(double)(i-1),1.0}).length();
    					}
    					else if(a[i]=='C'){
    						Vector v=(Point){(double)i-0.5,0.5}-(Point){0.5,sqrt(3.0)/2.0};
    						ans+=sqrt(sqr(v.length())-0.5*0.5);
    						v=Rotate(v,asin(0.5/v.length()));
    						Point p=(Point){0.5,sqrt(3.0)/2.0}+ans*unit(v);
    						double xian=((Vector){(double)i-0.5,1.0}-p).length();
    						double jiao=acos((sqr(xian)-0.5*0.5*2.0)/(-2.0*0.5*0.5));
    						ans+=jiao*0.5;
    					}
    				}
    				else{
    					if(a[i]=='S'){
    						ans+=2.0;
    					}
    					else if(a[i]=='C'){
    						ans+=PI*0.5;
    					}
    				}
    				I=i;
    				break;
    			}
    		}
    		for(int j=n,i=1;j>=1;++i,--j){
    			if(a[j]!='T'){
    				if(j!=n){
    					if(a[j]=='S'){
    						ans+=((Point){0.5,sqrt(3.0)/2.0}-(Point){(double)(i-1),1.0}).length();
    					}
    					else if(a[j]=='C'){
    						Vector v=(Point){(double)i-0.5,0.5}-(Point){0.5,sqrt(3.0)/2.0};
    						double d=sqrt(sqr(v.length())-0.5*0.5);
    						ans+=d;
    						v=Rotate(v,asin(0.5/v.length()));
    						Point p=(Point){0.5,sqrt(3.0)/2.0}+d*unit(v);
    						double xian=((Vector){(double)i-0.5,1.0}-p).length();
    						double jiao=acos((sqr(xian)-0.5*0.5*2.0)/(-2.0*0.5*0.5));
    						ans+=jiao*0.5;
    					}
    				}
    				else{
    					if(a[j]=='S'){
    						ans+=2.0;
    					}
    					else if(a[j]=='C'){
    						ans+=PI*0.5;
    					}
    				}
    				J=j;
    				break;
    			}
    		}
    		if(I!=1 && J!=n){
    			ans+=((double)(I-1)+1.0);
    			ans+=((double)(n-J)+1.0);
    			ans+=(double)(J-I+1);
    			if(a[I]=='S' && a[J]=='S'){
    				ans+=(double)(J-I+1);
    			}
    			else if(a[I]=='C' && a[J]=='C'){
    				ans+=(double)(J-I);
    			}
    			else{
    				ans+=((double)(J-I)+0.5);
    			}
    		}
    		else if(I==1 && J==n){
    			ans+=(double)(n-1)*2.0;
    		}
    		else if(I==1 && J!=n){
    			ans+=((double)(n-J)+1.0);
    			if(a[J]=='S'){
    				ans+=((double)J-0.5)*2.0;
    			}
    			else{
    				ans+=(((double)J-0.5)*2.0-0.5);
    			}
    			
    		}
    		else{
    			ans+=((double)(I-1)+1.0);
    			if(a[I]=='S'){
    				ans+=((double)(n-I+1)-0.5)*2.0;
    			}
    			else{
    				ans+=(((double)(n-I+1)-0.5)*2.0-0.5);
    			}
    		}
    		printf("%.11f
    ",ans);
    	}
    	return 0;
    }
  • 相关阅读:
    车牌定位与畸变校正(python3.7,opencv4.0)
    TensorFlow 2.0 Alpha/Beta pip安装指令
    pandas 获取数据帧DataFrame的行、列数
    pandas 对数据帧DataFrame中数据的增删、补全及转换操作
    pandas 对数据帧DataFrame中数据的索引及切片操作
    Exception: Exception caught in workbook destructor. Explicit close() may be required for workbook. 错误解决办法
    pandas对Excel文件的读写操作
    第一个WPF程序(串口调试)
    [C#]AdvPropertyGrid的使用示例(第三方控件:DevComponents.DotNetBar2.dll)
    C# 获得本地通用网卡信息
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7214336.html
Copyright © 2011-2022 走看看