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园,如下图所示,现在平面上有一些规格相同的信用卡,试求其凸包的周长.注意凸包未必是 ...
随机推荐
- mybatis06--动态sql
1.if标签 public interface StudentDao { /** *动态sql的查询 参数是Student对象 不确定 用户输入几个属性值 */ List<Student> ...
- Python学习之旅(三十五)
Python基础知识(34):电子邮件(Ⅰ) 几乎所有的编程语言都支持发送和接收电子邮件 在使用Python收发邮件前,请先准备好至少两个电子邮件,如xxx@163.com,xxx@sina.com, ...
- ie9 remove出错 jquery SCRIPT5007: 缺少对象
针对IE11 remove不起作用的问题. 其中IE11.0.37也不支持 IE11.0.42支持可能是由于客户机器设置了兼容模式的原因. 因为里面包含了object元素,移除数据的时候发生的bug. ...
- hadoop-1.0.1根目录下的jar包
- Codeforces 1136 - A/B/C/D/E - (Done)
链接:https://codeforces.com/contest/1136/ A - Nastya Is Reading a Book - [二分] #include<bits/stdc++. ...
- 2018秋寒假作业4—PTA编程总结1
7-1 打印沙漏 (20 分) 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个"*",要求按下列格式打印 所谓"沙漏形状",是指每行输出奇数个符 ...
- 安装配置Spark集群
首先准备3台电脑或虚拟机,分别是Master,Worker1,Worker2,安装操作系统(本文中使用CentOS7). 1.配置集群,以下步骤在Master机器上执行 1.1.关闭防火墙:syste ...
- day18:正则表达式和re模块
1,复习递归:返回值,不要只看到return就认为已经返回了,要看返回操作是在递归的第几层发生的,然后返回给了谁,如果不是返回给最外层函数,调用者就接收不到,需要再分析,看如何把结果返回回来,超过最大 ...
- 基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误
小结: 1. 锁的实现方式,按照应用的实现架构,可能会有以下几种类型: 如果处理程序是单进程多线程的,在 python下,就可以使用 threading 模块的 Lock 对象来限制对共享变量的同步访 ...
- 洛谷P2949 工作调度Work Scheduling [USACO09OPEN] 贪心
正解:贪心+并查集(umm不用并查集也成qwq 解题报告: 水题?主要感觉想到了俩方法然后还只实现了一个,怕忘了所以想着开个新坑记录下qwq 然后先放下传送门QAQ(哦这题和supermarket,双 ...