Convex Contour(数学,凸包)

题目描述

在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

输入样例1

4
TSTC

输出样例1

9.088434417

输入样例2

3
SCT

输出样例2

7.50914177324

题目大意: 给定若干个正三角形,正方形,圆形排列成一行,求包围他们一周所需要的最小长度。

由于知识淡薄,写题的时候并不知道知识点是凸包,但显然该题纯用数学也是可以计算的。

本题中不难看出,需要进行特殊处理的组合是当边界为三角形,而中端存在正方形或圆形,此时两种图形之间的最优连线为由边界三角形的顶点至正方形的顶点,或圆的切点。

请添加图片描述

其中,对于三角形与圆之间的连线除了切线外,还有切点到圆顶部的弧长,网上搜索公式代入即可。

而当序列全为三角形时,连线所呈现出的将是一个等腰梯形。

参考代码

#include <bits/stdc++.h>
using namespace std;
#define PI acos(-1)
const double C=0.5*sqrt(3.0);
double sanyuan(int n){
    
    
	double a=atan((C-0.5)/n);
	double b=asin(0.5/sqrt(n*n+(C-0.5)*(C-0.5)))-a;;
	double c=0.5*PI-a-b;
	return 0.5*(tan(c)+b);
}
int main(){
    
    
//	double h=sqrt(0.75);
//	double ans=6.5+sqrt((1-h)*(1-h)+1);
//	printf("%.9lf",ans);
	int n;cin>>n;
	double bian=1;
	string s;cin>>s;
	if(n==1){
    
    
		if(s[0]=='T')
			printf("%.9lf\n",bian*3.0);
		else if(s[0]=='S')
			printf("%.9lf\n",bian*4.0);
		else if(s[0]=='C')
			printf("%.9lf\n",1.0*bian*PI);
		return 0;
	}
	int num=0,nnum=0;
	if(s[0]=='T')
	for(int i=0;i<n;i++){
    
    
		if(s[i]=='T')num++;
		else break;
	}
	if(s[n-1]=='T')
	for(int i=n-1;i>=0;i--){
    
    
		if(s[i]=='T')nnum++;
		else break;
	}
//	cout<<num<<' '<<nnum<<endl;
	double h=sqrt(0.75);
	
	if(num==n||nnum==n){
    
    //全是三角 
	
		printf("%lf\n",2.0*n+1.0);
	}
	else{
    
    //和三角组合求一半 
		double ans=0;
		if(num!=0||nnum!=0){
    
    
			if(n-num-nnum-1>0) //zhongjian
				ans+=(n-num-nnum-1)*2;
				
			if(num!=0){
    
    
				if(s[num]=='S'){
    
    //连接第一个 
					ans=ans+sqrt((num-0.5)*(num-0.5)+(1-h)*(1-h))+2+num;
				}else{
    
    
					ans=ans+sanyuan(num)+1.5+num;
				}
			}
			if(nnum!=0){
    
    
				if(s[n-nnum-1]=='S'){
    
    
					ans=ans+sqrt((nnum-0.5)*(nnum-0.5)+(1-h)*(1-h))+2+nnum;
				}else{
    
    
					ans=ans+sanyuan(nnum)+1.5+nnum;
				}
			}
			if(s[0]=='S'){
    
    
				ans+=2;
			}else if(s[0]=='C'){
    
    
				ans+=PI/2;
			}
			if(s[n-1]=='S'){
    
    
				ans+=2;
			}else if(s[n-1]=='C'){
    
    
				ans+=PI/2;
			}
			printf("%.9lf\n",ans);
		}
		else{
    
    //两边均不三角形 
			ans=(n-2)*2;
			if(s[0]=='S'){
    
    
				ans+=3;
			}else if(s[0]=='C'){
    
    
				ans+=(1+PI/2);
			}
			if(s[n-1]=='S'){
    
    
				ans+=3;
			}
			if(s[n-1]=='C'){
    
    
				ans+=(1+PI/2);
			}
			printf("%.9lf\n",ans);
		}
		
		
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/laysan/article/details/120981602
今日推荐