思路

注意到结果就是每个信用卡边上的四个圆心的凸包周长+一个圆的周长

然后就好做了

注意平行时把距离小的排在前面,栈中至少要有1个元素(top>1),凸包中如果存在叉积为0的点也要pop,否则可能会错。

几个简单的向量的式子

\[a*b=(x_1y_1+ x_2y_2)
\]

\[a\times b=(x_1y_2- x_2y_1)
\]

逆时针旋转\(\theta\)度

\[x'=xcos\theta-ysin\theta\\
y'=xsin\theta+ycos\theta
\]

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
struct Vec{
double x,y;
Vec(){};
Vec(double xx,double yy){
x=xx;
y=yy;
}
double mul(Vec b){
return x*b.x+y*b.y;
}
double cross(Vec b){
return x*b.y-y*b.x;
}
Vec rev(double seta){
return Vec(x*cos(seta)-y*sin(seta),x*sin(seta)+y*cos(seta));
}
};
struct Point{
double x,y;
Point(){};
Point(double xx,double yy){
x=xx;
y=yy;
}
Point operator + (Point b){
return Point(x+b.x,y+b.y);
}
Point operator + (Vec b){
return Point(x+b.x,y+b.y);
}
Vec operator - (Point b){//b-a a->b
return Vec(b.x-x,b.y-y);
}
Point rev(Point b,double seta){//a 绕 b
return b+((Point(x,y))-b).rev(seta);
}
double dist(Point a){
return sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));
}
};
struct Stack{
int data[400100],topx=0;
void push(int x){
data[++topx]=x;
}
void pop(void){
topx--;
}
int top(void){
return data[topx];
}
int Setop(void){
return data[topx-1];
}
};
Point a[400100];
Stack S;
bool cmp(Point x,Point y){
return (x-a[1]).cross(y-a[1])>0||((x-a[1]).cross(y-a[1])==0&&x.dist(a[1])>y.dist(a[1]));
}
int n,cnt;
double ax,bx,rx,ans=0;
int main(){
scanf("%d",&n);
scanf("%lf %lf %lf",&ax,&bx,&rx);
for(int i=1;i<=n;i++){
double x,y,seta;
scanf("%lf %lf %lf",&x,&y,&seta);
a[++cnt]=Point(x-bx/2+rx,y+ax/2-rx).rev(Point(x,y),seta);
a[++cnt]=Point(x-bx/2+rx,y-ax/2+rx).rev(Point(x,y),seta);
a[++cnt]=Point(x+bx/2-rx,y+ax/2-rx).rev(Point(x,y),seta);
a[++cnt]=Point(x+bx/2-rx,y-ax/2+rx).rev(Point(x,y),seta);
}
// for(int i=1;i<=cnt;i++)
// printf("%lf %lf\n",a[i].x,a[i].y);
int pos=1;
for(int i=2;i<=cnt;i++)
if(a[i].x<a[pos].x||(a[i].x==a[pos].x&&a[i].y<a[pos].y))
pos=i;
swap(a[1],a[pos]);
sort(a+2,a+cnt+1,cmp);
S.push(1);
S.push(2);
for(int i=3;i<=cnt;i++){
while(S.topx>0&&(a[S.Setop()]-a[S.top()]).cross(a[S.Setop()]-a[i])<=0){
S.pop();
}
S.push(i);
}
int tt=S.top();
while(S.topx>1){
ans+=a[S.top()].dist(a[S.Setop()]);
S.pop();
}
ans+=a[S.top()].dist(a[tt]);
ans+=2*acos(-1.0)*rx;
printf("%.2lf\n",ans);
return 0;
}

P3829 [SHOI2012]信用卡凸包的更多相关文章

  1. luogu P3829 [SHOI2012]信用卡凸包 凸包 点的旋转

    LINK:信用卡凸包 当 R==0的时候显然是一个点的旋转 之后再求凸包即可. 这里先说点如何旋转 如果是根据原点旋转的话 经过一个繁杂的推导可以得到一个矩阵. [cosw,-sinw] [sinw, ...

  2. [洛谷P3829][SHOI2012]信用卡凸包

    题目大意:有$n$张一模一样的信用卡,每个角进行了圆滑处理,问这些卡组成的“凸包”的周长 题解:发现是圆滑处理的圆心围成的凸包加上一个圆周即可 卡点:输入长宽弄反,然后以为是卡精 C++ Code: ...

  3. 【BZOJ2829】[SHOI2012]信用卡凸包(凸包)

    [BZOJ2829][SHOI2012]信用卡凸包(凸包) 题面 BZOJ 洛谷 题解 既然圆角的半径都是一样的,而凸包的内角和恰好为\(360°\),所以只需要把圆角的圆心弄下来跑一个凸包,再额外加 ...

  4. [SHOI2012]信用卡凸包(凸包+直觉)

    这个题还是比较有趣. 小心发现,大胆猜想,不用证明! 我们发现所谓的信用卡凸包上弧的长度总和就是圆的周长! 然后再加上每个长宽都减去圆的直径之后的长方形的凸包周长即可! #include<ios ...

  5. Luogu-3829 [SHOI2012]信用卡凸包

    这道题的转化很巧妙,可以把信用卡四个角的圆心看做平面上的点来做凸包,\(ans\)就是凸包周长加上一个圆的周长 // luogu-judger-enable-o2 #include<cmath& ...

  6. [SHOI2012]信用卡凸包(计算几何)

    /* 考验观察法?? 可以发现最终答案等于所有作为圆心的点求出凸包的周长加上一个圆的周长 向量旋转 (x1, y1) 相较于 (x2, y2) 旋转角c 答案是 (dtx * cosc - dty * ...

  7. 【BZOJ 2829】 2829: 信用卡凸包 (凸包)

    2829: 信用卡凸包 Description Input Output Sample Input 2 6.0 2.0 0.0 0.0 0.0 0.0 2.0 -2.0 1.5707963268 Sa ...

  8. bzoj 2829 信用卡凸包(凸包)

    2829: 信用卡凸包 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1342  Solved: 577 [Submit][Status][Disc ...

  9. [BZOJ2829] 信用卡 (凸包)

    [BZOJ2829] 信用卡 (凸包) 题面 信用卡是一个矩形,唯四个角做了圆滑处理,使他们都是与矩形两边相切的1/4园,如下图所示,现在平面上有一些规格相同的信用卡,试求其凸包的周长.注意凸包未必是 ...

随机推荐

  1. ubuntu下安装go环境

    1.官网下载go语言安装包 地址:https://studygolang.com/dl 2.服务器上安装go 将下载下来的安装包解压到/usr/local下 tar xf go1.12.1.linux ...

  2. 软件毕业设计文档流程与UML图之间的关系

    每个模型都是用一种或者多种UML图来描述的,映射关系如下: 1.用例模型:使用用例图.顺序图.通信图.活动图和状态图来描述. 2.分析模型:使用类图和对象图(包括子系统和包).顺序图(时序图).通信图 ...

  3. exe电子书制作教程(超详细)【申明:来源于网络】

    exe电子书制作教程(超详细)[申明:来源于网络] 地址:http://wenku.baidu.com/view/0b046907eff9aef8941e0631.html

  4. PHP面试大全 基础篇100道问题

    2017年3月7日14:23:21 其实计划很久但是移植没时间去收集和处理弄成一个完整的文件 SVN地址: https://git.oschina.net/zxadmin/live_z 目前基础部分更 ...

  5. 使用FreeMarker生成word文档

    生成word文档的框架比较多,比如poi,java2word,itext和freemarker. 调研之后,freemarker来实现挺简单的,具体步骤如下: 1. 新建word文档,占位符用${}, ...

  6. Lint found fatal errors while assembling a release target

    1.Android 打包错误信息 Generate signed Bundle or APK  打包时,报了一个错,错误信息如下: Error:Execution failed for task ´: ...

  7. eclipse 安装 lombok插件

    下载插件 官网下载 :https://projectlombok.org/ 有些小伙伴官网可能打不开,现提供我的下载地址:https://files.cnblogs.com/files/niceyoo ...

  8. Centos下搭建邮件服务器

    一.协议 SMTP:用于发送邮件 POP3:用于接收邮件,接收后会将服务器上邮件删除 IMAP:用于接收邮件,接收后不会删除服务器邮件 二.几个重要的角色 MUA:可以理解为收取邮件的工具,比如thu ...

  9. Cartographer源码阅读(6):LocalTrajectoryBuilder和PoseExtrapolator

    LocalTrajectoryBuilder意思是局部轨迹的构建,下面的类图中方法的参数没有画进去. 注意其中的三个类:PoseExtrapolator类,RealTimeCorrelativeSca ...

  10. 开源搜素引擎:Lucene、Solr、Elasticsearch、Sphinx优劣势比较

    https://blog.csdn.net/belalds/article/details/82667692 开源搜索引擎分类 1.Lucene系搜索引擎,java开发,包括: Lucene Solr ...