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;
    }
  • 相关阅读:
    android PopupWindow实现从底部弹出或滑出选择菜单或窗口
    AndroidUI开源组件库BottomView 第三方自定义UI控件
    Android LayoutInflater详解
    Android设置上下边框或者左右边框
    杭州驾校模拟考试
    告诉你LTE-FDD与LTE-TDD的区别
    Android-Uiautomator:[5]停止monkey测试
    Android WebView
    解决Item控件抢占焦点
    ACM-计算几何之Quoit Design——hdu1007 zoj2107
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7214336.html
Copyright © 2011-2022 走看看