题目描述

一些几何图形整齐地在一个网格图上从左往右排成一列。它们占据了连续的一段横行,每个位置恰好一个几何图形。每个图形是以下的三种之一:
$1.$一个恰好充满单个格子的正方形。
$2.$一个内切于单个格子的圆。
$3.$一个底边与格子重合的等边三角形。

已知每个格子的边长都为$1$,请求出这些几何图形的凸包的周长。


输入格式

第一行包含一个正整数$n$,表示几何图形的个数。
第二行包含$n$个字符,从左往右依次表示每个图形,$"S"$表示正方形,$"C"$表示圆形,$"T"$表示等边三角形。


输出格式

输出一行一个实数,即凸包的周长。与答案的绝对或相对误差不超过$10^{-6}$时被认为是正确的。


样例

样例输入:

4
TSTC

样例输出:

9.088434417


数据范围与提示

$1\leqslant n\leqslant 20$


题解

突然看到自己刚学$OI$时的题解,已经是一年前的题解了(有同学说,一年前的我都能掉打现在的他),那是满是美好的回忆,没有现在临近$CSP-S$痛苦的日常。

附上一年前的题解链接:题解 P3680 【[CERC2016]凸轮廓线 Convex Contour】

上面这篇题解中有错误(还是当时菜),评论区已经有人指正了,在此不再赘述。

这天又打了一遍,在原来的基础上讲一讲自己现在对这道题的心得和体会。

不知道为什么数据范围是$20$,总之我的时间复杂度是$\Theta(n)$的……

显然中间无论是什么形状都是无所谓的,因为无论是什么图形

先来考虑正方形和圆形在两端的情况,这样会简单很多,因为它们的高度都是$1$,这样我们无非就是需要考虑两头是什么形状就好了:

  $\alpha.$如果两头都是正方形,那么答案就是$2\times n+2\downarrow$

  

  $\beta.$如果是一个正方形,一个圆形,答案就是$2\times n+\dfrac{\frac{\sqrt{3}}{2}\pi}{2}$

  

  $\gamma.$如果两头都是圆形,那么答案就是$2\times n-2+\pi\downarrow$

  

再来考虑三角形在两端的情况,远没有你想象的简单。

你以为是这样的:

然而是事实这样的:

于是你就弃掉了它……

如果你还能看到这里,就说明你还有希望,那么我们先来考虑三角形在一头,下一个是正方形的情况:

你以为是这样:

然而事实又是这样:

难点在于处理“悬空”的那条线的长度,但是我们发现了如下的一个直角三角形:

可以先求出来这个直角三角形的两个直角边的长度再通过勾股定理求出斜边长,不妨对这个直角三角形作出如下定义:

因为边长为$1$的等边三角形的高为$\frac{sqrt{3}}{2}$,所以我们可以知道$a=1-\frac{sqrt{3}}{2}$,$b$很好求,就是开头三角形的个数$-0.5$。

三角形在最后同理,在此不再赘述。

于是我们解决了三角形$+$正方形的情况。

考虑最后的也是最难的三角形$+$圆形的情况:

你以为是这样的:

然而事实又是这样:

上图中粗的红线是圆的切线,那么我们又可以找到一个三角形:

不妨再做出如下定义:

$a$就是圆形边长,很好求,难点变成了求$b$。

再回到上一张图,又发现了一个三角形:

再放大这个三角形:

$d$就是$\sqrt{3}-1$,$e$则是开头三角形的个数,于是我们可以得到$b$。

所有情况枚举完了,这道题也就轻松解决了。

时间复杂度:$\Theta(n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
char ch[20];
double ans,p;
int n,flag;
int main()
{
scanf("%d%s",&n,ch+1);
ans+=n-1;
if(ch[1]=='C')flag=2,ans+=M_PI/2;
if(ch[n]=='C')ans+=M_PI/2;
if(ch[1]=='T')p+=1.0,flag=0,ans+=1.5;
if(ch[n]=='T')ans+=1.5;
if(ch[1]=='S')flag=1,ans+=2.5;
if(ch[n]=='S')ans+=1.5;
for(int i=2;i<=n;i++)
switch(ch[i])
{
case 'T':p+=1.0;break;
case 'S':
switch(flag)
{
case 0:
ans+=sqrt((p-0.5)*(p-0.5)+(7.0/4.0-sqrt(3)))+1.0;
p=0;
flag=1;
break;
case 1:
ans+=p+1.0;
p=0;
break;
case 2:
ans+=p+1.5;
p=0;
flag=1;
break;
}
break;
case 'C':
switch(flag)
{
case 0:
{
double x=1.0*(p);
double y=(sqrt(3)/2.0-0.5);
double z=sqrt(x*x+1.0-sqrt(3)/2.0);
double len1=sqrt(x*x+1.0-sqrt(3)/2.0-0.25);
double o=M_PI/2.0-atan(y/x)-acos(0.5/z);
double len2=0.5*o;
p=0;
ans+=len1+len2;
flag=2;
}
break;
case 1:
ans+=p+0.5;
p=0;
flag=2;
break;
case 2:
ans+=p+1.0;
p=0;
break;
}
break;
}
if(p)
switch(flag)
{
case 0:ans+=p-1.0;break;
case 1:ans+=sqrt((p-0.5)*(p-0.5)+(7.0/4.0-sqrt(3)));break;
case 2:
{
double x=1.0*(p);
double y=(sqrt(3)/2.0-0.5);
double z=sqrt(x*x+1.0-sqrt(3)/2.0);
double len1=sqrt(x*x+1.0-sqrt(3)/2.0-0.25);
double o=M_PI/2.0-atan(y/x)-acos(0.5/z);
double len2=0.5*o;
ans+=len1+len2;
}
break;
}
printf("%.9lf",ans);
return 0;
}

rp++

[CERC2016]:凸轮廓线Convex Contour(模拟+数学)的更多相关文章

  1. poj-3899-The Lucky Numbers 模拟+数学

    题目链接: http://poj.org/problem?id=3899 题目意思: 求给定区间内,只含4.7的数的个数以及通过反转后在该区间内的个数和. 解题思路: 模拟+数学. 代码解释的很详细, ...

  2. Codeforces Round #284 (Div. 2)A B C 模拟 数学

    A. Watching a movie time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. 洛谷3月月赛div2 题解(模拟+数学+贪心+数学)

    由于本人太蒻了,div1的没有参加,胡乱写了写div2的代码就赶过来了. T1 苏联人 题目背景 题目名称是吸引你点进来的. 这是一道正常的题,和苏联没有任何关系. 题目描述 你在打 EE Round ...

  4. Codeforces Round #382 (Div. 2) (模拟|数学)

    题目链接: A:Ostap and Grasshopper B:Urbanization C:Tennis Championship D:Taxes 分析:这场第一二题模拟,三四题数学题 A. 直接模 ...

  5. [CERC2016]凸轮廓线

    题意 https://www.luogu.org/problem/P3680 思考 拆点即可. 注意精度. 代码 // luogu-judger-enable-o2 #include<bits/ ...

  6. Codeforces 101173 C - Convex Contour

    思路: 如果所有的图形都是三角形,那么答案是2*n+1 否则轮廓肯定触到了最上面,要使轮廓线最短,那么轮廓肯定是中间一段平的 我们考虑先将轮廓线赋为2*n+2,然后删去左右两边多余的部分 如果最左边或 ...

  7. UVALive 7749 Convex Contour (计算几何)

    题意:给定上正方形,圆,三角形,让你求出包围它的最短的路径. 析:首先,如果是这种情况  三角形 三角形 三角形 正方形(圆) 三角形 三角形 三角形 ..这一种就是直接从左边直接连到正方形(圆),也 ...

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

    注意等边三角形的上顶点是卡不到边界上的. 于是整个凸包分成三部分:左边的连续的三角形.中间的.右边的连续的三角形. 套个计算几何板子求个三角形顶点到圆的切线.三角形顶点到正方形左上角距离啥的就行了,分 ...

  9. HDU1215 七夕节(模拟 数学)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1215 七夕节 Time Limit: 2000/1000 MS (Java/Others)    Me ...

随机推荐

  1. python文件打包/导入 .so 文件

    打包so文件 见: http://www.cnblogs.com/ke10/p/py2so.html 导入so文件 import sys sys.path.append(r'/home/project ...

  2. Mysql数据库在建表时指定engine等于InnoDB 或MyISAM的意义

    一.ISAM和InnoDB的定义 1. ISAM ISAM是一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到数据库被查询的次数要远大于更新的次数.因此,ISAM执行读取操作的速度很快 ...

  3. Spring基础08——使用p命名空间

    1.使用p命名空间 为了简化xml配置,越来越多的xml文件采用属性而非子元素配置信息,Spring从2.5版本开始引入了一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean ...

  4. 面试编程题拾遗(06) --- 打印n对括号的全部有效组合

    如题所述,当n=3时,可能的组合有:(()()), ((())), ()(()), (())(), ()()() 代码如下(有注释): import java.util.ArrayList; impo ...

  5. 配置阿里云SLB全站HTTPS集群(以下内容仅为流程,信息可能有些对应不上)

    1)登录阿里云购买两台实例 1.1) 按量付费购买两台实例 1.2) 配置网络可以不选择分配外网 1.3) 自定义密码 1.4) 购买完成 1.5) 实例列表 2)购买SLB实例 2.1)按量付费购买 ...

  6. Python列表(list)的方法调用

    #list# n = [12,34,"yue"]# v = n.append(27) #增加元素,注意是在尾部增加,由于列表是可修改的,所以是在原列表中增加,与字符串存在区别# p ...

  7. CCPC-Wannafly Winter Camp Day1 (Div2) 吃豆豆 (DP)

    题目描述 wlswls在玩一个游戏. wlswls有一个nn行mm列的棋盘,对于第ii行第jj列的格子,每过T[i][j]T[i][j]秒会在上面出现一个糖果,第一次糖果出现在第T[i][j]T[i] ...

  8. java术语(PO/POJO/VO/BO/QO/DAO/DTO)

    一.概念理解 ​ 这些概念用于描述对象的类型:由于java是面向对象的语言:程序的世界就是各个对象之间的"交互":在交互的工程中会存在多个层次,每个层次中所拥有(关注)的内容都是不 ...

  9. vue项目中打包background背景路径问题

    项目中图片都放在src/img文件夹,img和background-image引用都用相对路径,即../../这种形式 在打包build的设置路径assetsPublicPath: ‘./‘,然后那些 ...

  10. Python---进阶---文件操作---搜索文件和保存搜索结果

    ### 编写一个程序,用户输入文件名以及开始搜索的路径,搜索该文件是否存在,如果遇到文件夹,则进入该文件夹继续搜索 - input 去接受用户输入的文件名和开始搜索的路径 - os.path.isdi ...