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园,如下图所示,现在平面上有一些规格相同的信用卡,试求其凸包的周长.注意凸包未必是 ...
随机推荐
- 转 基于Excel参数化你的Selenium2测试
转载:https://blog.csdn.net/zhusongziye/article/details/80100375 前言 今天我们就如何使用xlrd模块来进行python selenium2 ...
- JavaScript基础知识(函数)
函数的基础 函数: 把实现相同功能的代码放到一个函数体中,当想实现这个功能时,直接执行这个函数即可:减少了的冗余:高内聚,低耦合--> 函数的封装: 函数:引用数据类型: var a = 10; ...
- Tensorflow 的saved_model模块学习
saved_model模块主要用于TensorFlow Serving.TF Serving是一个将训练好的模型部署至生产环境的系统,主要的优点在于可以保持Server端与API不变的情况下,部署新的 ...
- awt
public class MouseTest extends Frame{ private static final long serialVersionUID = 54376853365952763 ...
- 范进中Nature——儒林外史新义
范进中Nature——儒林外史新义 范进发了文章回办公室,实验室一块儿搬砖的挂名作者俱各欢喜.正待烧锅煮方便面,只见他老板胡副教授,手里拿着一包外卖和一瓶红星二锅头,走了进来.范进向他作揖,坐下.胡副 ...
- 【English】【托业】【四六级】写译高频词汇
大家都知道,四六级翻译每次考的话题不可能原句直接重复,但是,在研究了近几年的四六级真题后,我们惊奇地发现: 写译词汇在重复考! 写译词汇在重复考! 写译词汇在重复考! 因此,小编为大家整理了四六级写译 ...
- JDK 1.8 JVM的变化
前言: 1.什么是JVM JVM的全称是 Java Virtual Machine(Java虚拟机),它通过模拟一个计算机来达到一个计算机所具有的功能. Java和实体计算机一样也必须有一套合适的指令 ...
- git 常用命令收集
1. 查看某文件的历史递交记录git log --pretty=oneline 文件名 2. 查看远程仓库信息 git remote show origin 3. 查看用户名和修改用记名: git c ...
- PHP提交表单失败后如何保留填写的信息
index.html模板文件大内容: <html> <head> <title>jQuery Ajax 实例演示</title> </head&g ...
- 看懂MSSQL执行计划,分析SQL语句执行情况
打开SQL执行计划窗口 执行计划的图表是从右向左看的 SQL Server有几种方式查找数据记录 [Table Scan] 表扫描(最慢),对表记录逐行进行检查 [Clustered Index Sc ...