P3829 [SHOI2012]信用卡凸包
思路
注意到结果就是每个信用卡边上的四个圆心的凸包周长+一个圆的周长
然后就好做了
注意平行时把距离小的排在前面,栈中至少要有1个元素(top>1),凸包中如果存在叉积为0的点也要pop,否则可能会错。
几个简单的向量的式子
\]
\]
逆时针旋转\(\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]信用卡凸包的更多相关文章
- luogu P3829 [SHOI2012]信用卡凸包 凸包 点的旋转
LINK:信用卡凸包 当 R==0的时候显然是一个点的旋转 之后再求凸包即可. 这里先说点如何旋转 如果是根据原点旋转的话 经过一个繁杂的推导可以得到一个矩阵. [cosw,-sinw] [sinw, ...
- [洛谷P3829][SHOI2012]信用卡凸包
题目大意:有$n$张一模一样的信用卡,每个角进行了圆滑处理,问这些卡组成的“凸包”的周长 题解:发现是圆滑处理的圆心围成的凸包加上一个圆周即可 卡点:输入长宽弄反,然后以为是卡精 C++ Code: ...
- 【BZOJ2829】[SHOI2012]信用卡凸包(凸包)
[BZOJ2829][SHOI2012]信用卡凸包(凸包) 题面 BZOJ 洛谷 题解 既然圆角的半径都是一样的,而凸包的内角和恰好为\(360°\),所以只需要把圆角的圆心弄下来跑一个凸包,再额外加 ...
- [SHOI2012]信用卡凸包(凸包+直觉)
这个题还是比较有趣. 小心发现,大胆猜想,不用证明! 我们发现所谓的信用卡凸包上弧的长度总和就是圆的周长! 然后再加上每个长宽都减去圆的直径之后的长方形的凸包周长即可! #include<ios ...
- Luogu-3829 [SHOI2012]信用卡凸包
这道题的转化很巧妙,可以把信用卡四个角的圆心看做平面上的点来做凸包,\(ans\)就是凸包周长加上一个圆的周长 // luogu-judger-enable-o2 #include<cmath& ...
- [SHOI2012]信用卡凸包(计算几何)
/* 考验观察法?? 可以发现最终答案等于所有作为圆心的点求出凸包的周长加上一个圆的周长 向量旋转 (x1, y1) 相较于 (x2, y2) 旋转角c 答案是 (dtx * cosc - dty * ...
- 【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 ...
- bzoj 2829 信用卡凸包(凸包)
2829: 信用卡凸包 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1342 Solved: 577 [Submit][Status][Disc ...
- [BZOJ2829] 信用卡 (凸包)
[BZOJ2829] 信用卡 (凸包) 题面 信用卡是一个矩形,唯四个角做了圆滑处理,使他们都是与矩形两边相切的1/4园,如下图所示,现在平面上有一些规格相同的信用卡,试求其凸包的周长.注意凸包未必是 ...
随机推荐
- TemplateBuilder Android Studio
TemplateBuilder:是Android Studio的一个开发模板,大大提高开发效率.
- js中的 substr方法与substring方法 不同
一个参数时: 二者同为 从 第参数个 开始截取,一直到str 末尾,并返回. 二个参数时: substr(a,b): 从第a个字符开始, 截取b个. substring(a,b): 从第a个字符 ...
- elk-filebeat-(效果图示)(四)
一.vim filebeat-6.3.2-linux-x86_64/filebeat.yml - type: log # Change to true to enable this input con ...
- JQuery限制文本框只能输入数字和小数点的方法
<input type="text" class="txt NumText" Width="100px" /> $(func ...
- bug制造者又上线了
上一家公司,领导经常这样表扬一位同事,“你写的bug远比你的功能值钱...” 今天特么的突然觉得我好像也有这样的功能,不知道是上次回家把脑子落家里了还是,前几天淋雨脑子进了水了. 呢么简单一个功能,愣 ...
- java应用,直接请求没问题,通过nginx跳转状态吗400
今天配置金融的测试环境,直接调用java应用返回状态200,通通过nginx跳转,会返回400,真是一头雾水..... 参考文档: https://www.cnblogs.com/yanghj010/ ...
- 1 创建一个存储过程,以及对存储过程的调用 MySQL
1 首先创建一张tb1表 sql语句如下 CREATE TABLE `tb1` ( `Id` int(11) NOT NULL AUTO_INCREMENT, `age` int(11) DE ...
- yum安装openjdk
含有的命令:yum,java -version,javac,source,vim [root@ycj ~]# yum -y install java-1.8.0-openjdk-devel //安装j ...
- 单片机小白应该如何学习stm32的一些实践心得!
嵌入式搬砖道路上的大三狗一枚,撑死算个初学者吧.才学有限,下面仅仅是本人对STM32学习的一点心得与建议,希望对题主有帮助吧. 心得:本人当初学习STM32的时候有一些跟风的因素,自以为学的芯片越多就 ...
- MacOS High Sierra 引起 VirtualBox Vagrant 同步慢
问题 最近把mac的操作系统升级到了最新版本发现了一个问题,通过共享文件夹的方式 修改的文件,无法立即同步到虚拟机中,大概需要30秒才能同步到共享文件夹. 操作环境如下 虚拟机:Virtualbox ...