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

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

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

#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;
}

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

  1. dp+分类讨论 Gym 101128E

    题目链接:http://codeforces.com/gym/101128 感觉这个人写的不错的(我只看了题目大意):http://blog.csdn.net/v5zsq/article/detail ...

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

    国际惯例的题面: 这题让我爆肝啦......这种计数显然容斥,正好不含任何坏点的我们不会算,但是我们能算至少含零个坏点的,至少含一个坏点的,至少含两个坏点的......所以最终的答案就是(至少含零个坏 ...

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

    题意:从区间[L,R]中选取不多于k个数,使这些数异或和尽量小,输出最小异或和以及选取的那些数. 解法:分类讨论. 设选取k个数. 1. k=4的时候如果区间长度>=4且L是偶数,那么可以构造四 ...

  4. BZOJ-1067 降雨量 线段树+分类讨论

    这道B题,刚的不行,各种碎点及其容易忽略,受不鸟了直接 1067: [SCOI2007]降雨量 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 2859 ...

  5. UVaLive 6862 Triples (数学+分类讨论)

    题意:给定一个n和m,问你x^j + y^j = z^j 的数量有多少个,其中0 <= x <= y <= z <= m, j = 2, 3, 4, ... n. 析:是一个数 ...

  6. 枚举(分类讨论):BZOJ 1177: [Apio2009]Oil

    1177: [Apio2009]Oil Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1477  Solved: 589[Submit] Descri ...

  7. Educational Codeforces Round 63 (Rated for Div. 2) D. Beautiful Array 分类讨论连续递推dp

    题意:给出一个 数列 和一个x 可以对数列一个连续的部分 每个数乘以x  问该序列可以达到的最大连续序列和是多少 思路: 不是所有区间题目都是线段树!!!!!! 这题其实是一个很简单的dp 使用的是分 ...

  8. 【cf789B】Masha and geometric depression(分类讨论/暴力)

    B. Masha and geometric depression 题意 在黑板上写数列,首项是b,公比是q,超过l时就停止不写.给定m个数,遇到后跳过不写.问一共写多少个数,如果无穷个输出inf. ...

  9. P2331 [SCOI2005]最大子矩阵 (动规:分类讨论状态)

    题目链接:传送门 题目: 题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 输入输出格式 输入格式: 第一行为n,m,k( ...

随机推荐

  1. MSSQL 视图/事务(TRAN[SACTION])/存储过程(PROC[EDURE])/触发器(TRIGGER )

    --视图 视图是一张虚拟表,它表示一张表的部分数据或多张表的综合数据,其结构和数据是建立在对表的查询基础上 视图在操作上和数据表没有什么区别,但两者的差异是其本质是不同: 数据表是实际存储记录的地方, ...

  2. Python3 PyPAML 模块(配置文件的操作)

    YAML 是专门用来写配置文件的语言,非常简洁和强大 它的基本语法规则如下: 1.大小写敏感 2.使用缩进表示层级关系 3.缩进时不允许使用Tab键,只允许使用空格. 4.缩进的空格数目不重要,只要相 ...

  3. System V共享内存介绍

    (一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...

  4. Yii 1.1.17 五、分页类、关联模型、权限验证与默认页面跳转

    一.分页类使用 1.在控制器中 // 实例化 $criteria = new CDbCriteria(); $articleModel = Article::model(); // 分页 $total ...

  5. DIV+CSS综合实例【传智PHP首页】

    1.首页结构 2.准备工作 所有素材放到与当前网页同级的目录下: 网页背景色.背景图: 主页宽度:1000px: 创建CSS文件,将CSS文件引入到当前的HTML文件中. 3.实现 效果图: HTML ...

  6. MVC 从控制器将数据对象赋值给前端JS对象

    @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...

  7. 动画基础--基于Core Animation(3)

    参考:https://zsisme.gitbooks.io/ios-/content/ 前面的文章动画基础--基于Core Animation(1),动画基础--基于Core Animation(2) ...

  8. C# 笔记——排序

    首先,一张图看懂8中排序之间的关系: 平均速度最快:快速排序 所需辅助空间最多:归并排序 所需辅助空间最少:堆排序 不稳定:快速排序,希尔排序,堆排序. 1. 直接插入排序 基本思想:在要排序的一组数 ...

  9. Leetcode 之Longest Common Prefix(33)

    在一组字符串中找到最长的子串.采用纵向匹配,遇到第一个不匹配的停止. string longestComPrefix(vector<string> &strs) { if (str ...

  10. node中--save跟--save--dev

    --save参数表示将该模块写入dependencies属性, --save-dev表示将该模块写入devDependencies属性.   dependencies字段指定了项目运行所依赖的模, d ...