【计算几何】【分类讨论】Gym - 101173C - Convex Contour

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

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

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

#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\n",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\n",ans);
	}
	return 0;
}
时间: 2024-10-24 02:24:44

【计算几何】【分类讨论】Gym - 101173C - Convex Contour的相关文章

dp+分类讨论 Gym 101128E

题目链接:http://codeforces.com/gym/101128 感觉这个人写的不错的(我只看了题目大意):http://blog.csdn.net/v5zsq/article/details/61428924 Description n个小木条,一段前面有一个小箭头,给出第一个小木条的非箭头端端点横坐标以及每个小木条箭头端的坐标,现在要从下往上把这n'个木条按顺序叠放好,要求相邻两个小木条必须有一个共同端点且有交叠部分,问小木条有多少种放法 Input 第一行一整数n表示木条数量,之

Bzoj4558:分类讨论 计算几何 组合数学

国际惯例的题面: 这题让我爆肝啦......这种计数显然容斥,正好不含任何坏点的我们不会算,但是我们能算至少含零个坏点的,至少含一个坏点的,至少含两个坏点的......所以最终的答案就是(至少含零个坏点的-至少含一个坏点的+至少含两个坏点的-至少含三个坏点的+至少含四个坏点的).然后就是怎么计算的问题.对于至少含零个坏点的,我们不妨设定所有点都是好点.对于非正放的正方形,我们能找到一个正好包含它的最小的正放的正方形,显然这样的正方形是唯一的. 然后我们让四个点在这个正方形的边上滑动,显然这四个点

【线段树】【分类讨论】水果姐逛水果街Ⅰ

3304 水果姐逛水果街Ⅰ 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 水果姐今天心情不错,来到了水果街. 水果街有n家水果店,呈直线结构,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样. 学过oi的水果姐迅速发现了一个赚钱的方法:在某家水果店买一个水果,再到另外一家店卖出去,赚差价. 就在水果姐窃喜的时候,cgh突然出现,他为了为难水果姐,给出m个问题,每个问题要求水果姐从第x家店出发到第y家店

BZOJ 1067 降雨量(RMQ+有毒的分类讨论)

1067: [SCOI2007]降雨量 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 4399  Solved: 1182 [Submit][Status][Discuss] Description 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意 Y<Z<X,Z年的降雨量严格小于X年.例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890, 则可以说

cf 251 B Playing with Permutations 暴力 分类讨论

题链;http://codeforces.com/problemset/problem/251/B B. Playing with Permutations time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Little Petya likes permutations a lot. Recently his mom has p

BZOJ 1099([POI2007]树Drz-9次线段树&amp;分类讨论+线段树与插入顺序维护2个参数)

1099: [POI2007]树Drz Time Limit: 15 Sec  Memory Limit: 162 MB Submit: 142  Solved: 55 [Submit][Status] Description CDQZ是一个偏远的小学校,FGD在学校里中了一排树.他却不喜欢这些树的顺序,因为他们高高矮矮显得那么参差不齐. FGD定义这些树的不整齐程度为相邻两树的高度差的和.设树高分别为h1,h2,h3,-,hn.那么不整齐程度定义为:|h1-h2|+|h2-h3|+--+|hn

POJ 2826 An Easy Problem?!(线段相交,分类讨论)

题意:给两个线段,问他们能收集到多少雨水. 链接:http://poj.org/problem?id=2826 解法:分四种情况讨论 1. 存在一个线段与x轴平行,答案为0 2. 两个线段没有交点,答案为0 3. 1和2都不满足时,令线段1为比较低的那个线段,且p1为其比较高的那个点,若该点往y轴正方向的射线与线段2有交点,则答案为0 4. 3不满足时,求出两线段交点x1,p1做一条平行于x轴的线,该线与线段2的交点x2,则三角形x1, x2, p1的面积就是答案 小结:此题属于分类讨论型的题,

Codeforces 460D Little Victor and Set --分类讨论+构造

题意:从区间[L,R]中选取不多于k个数,使这些数异或和尽量小,输出最小异或和以及选取的那些数. 解法:分类讨论. 设选取k个数. 1. k=4的时候如果区间长度>=4且L是偶数,那么可以构造四个数(L,L+1,L+2,L+3),这样的话(L^(L+1)) ^ ((L+2)^(L+3)) = 0,最优 如果L不是偶数,那么看从L+1到R有没有四个数,如果有则取该四个数,否则最小异或和达不到0,也达不到1了,不再考虑k=4,k=3时还有可能等于0,所以转到k=3 2. k=3时,要使异或和为0,那

【树链剖分】【dfs序】【LCA】【分类讨论】Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

一棵树,q次询问,每次给你三个点a b c,让你把它们选做s f t,问你把s到f +1后,询问f到t的和,然后可能的最大值是多少. 最无脑的想法是链剖线段树--但是会TLE. LCT一样无脑,但是少一个log,可以过. 正解是分类讨论, 如果t不在lca(s,f)的子树内,答案是dis(lca(s,f),f). 如果t在lca(s,f)的子树内,并且dep(lca(s,t))>dep(lca(f,t)),答案是dis(lca(s,t),f): 否则答案是dis(lca(f,t),f). #in