luogu P3829 [SHOI2012]信用卡凸包 凸包 点的旋转
LINK:信用卡凸包
当 R==0的时候显然是一个点的旋转 之后再求凸包即可。
这里先说点如何旋转 如果是根据原点旋转的话 经过一个繁杂的推导可以得到一个矩阵。
[cosw,-sinw]
[sinw,cosw] 这个矩阵就是旋转矩阵 乘一下当前的坐标 [x,y] 就可以得到逆时针旋转w度的答案。
具体的 x'=xcosw-ysinw; y'=xsinw+ycosw.
顺时针转换一下即可。接下来考虑绕某个点进行旋转。
既然已经得到了绕原点旋转的方法了 此时让要旋转点的坐标减参考系的点的坐标 此时就可以把这个参考系的点当做原点了。
直接进行旋转最后回归原坐标系再加回来即可。
回到这道题,除了凸包还有比较ex的圆。
有圆我们只单单求出来凸包是不准的。
还是考虑换成多边形。可以发现将每个圆心链接起来求出的多边形的长度比原来的恰好少一个圆的周长。
多画几个图也是这样的。所以这道题就变成了求凸包的长度+一个圆的周长。
const int MAXN=100010;
const db Pi=acos(-1.0);
struct Vec
{
db x,y;Vec(){}Vec(db _x,db _y){x=_x;y=_y;}
inline Vec operator +(Vec b){return Vec(x+b.x,y+b.y);}
inline Vec operator -(Vec b){return Vec(x-b.x,y-b.y);}
inline Vec operator -(){return Vec(-x,-y);}
inline db operator *(Vec b){return x*b.x+y*b.y;}//点积
inline db operator %(Vec b){return x*b.y-b.x*y;}//叉积
inline db operator ~(){return x*x+y*y;}//模长的平方
inline bool operator ==(Vec b){return fabs(x-b.x)<=EPS&&fabs(y-b.y)<=EPS;}
inline bool operator !=(Vec b){return fabs(x-b.x)>EPS||fabs(y-b.y)>EPS;}
inline Vec Unit(){db _=sq(x*x+y*y);return Vec(x/_,y/_);}//单位化
inline Vec Norm(){db _=sq(x*x+y*y);return Vec(-y/_,x/_);}//单位法向量
inline bool Quad(){return y>EPS||(fabs(y)<=EPS&&x>=-EPS);}
inline bool operator <(Vec b){return fabs(y-b.y)<=EPS?x<b.x:y<b.y;}
};typedef Vec pt;
inline Vec operator /(Vec a,db k){return Vec(a.x/k,a.y/k);}
inline Vec operator *(db k,Vec a){return Vec(a.x*k,a.y*k);}
inline Vec operator *(Vec a,db k){return Vec(a.x*k,a.y*k);}
inline bool para(Vec a,Vec b){return fabs(a%b)<=EPS;}//判断a b是否平行
inline bool Toleft(Vec a,Vec b){return b%a>EPS;}//判断a是否在b的左边
inline void O(pt a,char c=' '){printf("(%.3lf,%.3lf)%c",a.x,a.y,c);}
int n,top,cnt;
pt a[MAXN],s[MAXN],LTL;
db A,B,R;
inline bool cmpltl(pt a,pt b){return para(a=a-LTL,b=b-LTL)?~a<~b:Toleft(b,a);}
signed main()
{
freopen("1.in","r",stdin);
gt(n);
gi(A);gi(B);gi(R);
rep(1,n,i)
{
db x,y,w;
gi(x);gi(y);gi(w);
db s1=B/2-R;db s2=A/2-R;
db xx=s1,yy=s2;
db sx=xx*cos(w)-yy*sin(w);
db sy=xx*sin(w)+yy*cos(w);
a[++cnt]=Vec(sx+x,sy+y);
xx=-s1;yy=-s2;
sx=xx*cos(w)-yy*sin(w);
sy=xx*sin(w)+yy*cos(w);
a[++cnt]=Vec(sx+x,sy+y);
xx=s1;yy=-s2;
sx=xx*cos(w)-yy*sin(w);
sy=xx*sin(w)+yy*cos(w);
a[++cnt]=Vec(sx+x,sy+y);
xx=-s1;yy=s2;
sx=xx*cos(w)-yy*sin(w);
sy=xx*sin(w)+yy*cos(w);
a[++cnt]=Vec(sx+x,sy+y);
}
LTL=*min_element(a+1,a+1+cnt);
//rep(1,cnt,i)O(a[i],'\n');
sort(a+1,a+1+cnt,cmpltl);
rep(1,cnt,i)
{
while(top>1&&!Toleft(a[i]-s[top-1],s[top]-s[top-1]))--top;
s[++top]=a[i];
}
db ans=0;s[top+1]=s[1];
rep(1,top,i)ans+=sq(~(s[i+1]-s[i]));
ans+=2*Pi*R;
printf("%.2lf",ans);
return 0;
}
luogu P3829 [SHOI2012]信用卡凸包 凸包 点的旋转的更多相关文章
- P3829 [SHOI2012]信用卡凸包
思路 注意到结果就是每个信用卡边上的四个圆心的凸包周长+一个圆的周长 然后就好做了 注意平行时把距离小的排在前面,栈中至少要有1个元素(top>1),凸包中如果存在叉积为0的点也要pop,否则可 ...
- [洛谷P3829][SHOI2012]信用卡凸包
题目大意:有$n$张一模一样的信用卡,每个角进行了圆滑处理,问这些卡组成的“凸包”的周长 题解:发现是圆滑处理的圆心围成的凸包加上一个圆周即可 卡点:输入长宽弄反,然后以为是卡精 C++ Code: ...
- 【BZOJ2829】[SHOI2012]信用卡凸包(凸包)
[BZOJ2829][SHOI2012]信用卡凸包(凸包) 题面 BZOJ 洛谷 题解 既然圆角的半径都是一样的,而凸包的内角和恰好为\(360°\),所以只需要把圆角的圆心弄下来跑一个凸包,再额外加 ...
- Luogu P2742 模板-二维凸包
Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...
- POJ 3608 Bridge Across Islands --凸包间距离,旋转卡壳
题意: 给你两个凸包,求其最短距离. 解法: POJ 我真的是弄不懂了,也不说一声点就是按顺时针给出的,不用调整点顺序. 还是说数据水了,没出乱给点或给逆时针点的数据呢..我直接默认顺时针给的点居然A ...
- Luogu-3829 [SHOI2012]信用卡凸包
这道题的转化很巧妙,可以把信用卡四个角的圆心看做平面上的点来做凸包,\(ans\)就是凸包周长加上一个圆的周长 // luogu-judger-enable-o2 #include<cmath& ...
- [SHOI2012]信用卡凸包(凸包+直觉)
这个题还是比较有趣. 小心发现,大胆猜想,不用证明! 我们发现所谓的信用卡凸包上弧的长度总和就是圆的周长! 然后再加上每个长宽都减去圆的直径之后的长方形的凸包周长即可! #include<ios ...
- [SHOI2012]信用卡凸包(计算几何)
/* 考验观察法?? 可以发现最终答案等于所有作为圆心的点求出凸包的周长加上一个圆的周长 向量旋转 (x1, y1) 相较于 (x2, y2) 旋转角c 答案是 (dtx * cosc - dty * ...
- BZOJ2829信用卡凸包——凸包
题目描述 输入 输出 样例输入 2 6.0 2.0 0.0 0.0 0.0 0.0 2.0 -2.0 1.5707963268 样例输出 21.66 提示 本样例中的2张信用卡的轮廓在上图中用实线标出 ...
随机推荐
- CF796C Bank Hacking 题解
洛谷链接 题目 Although Inzane successfully found his beloved bone, Zane, his owner, has yet to return. To ...
- Android/iOS内嵌Unity开发示例
Unity 与 Android/iOS 交叉开发主要有两种方式,以 Android 为例,一是 Android 生成 jar 或者 aar 包,导入到 unity3d plugin/bin/ 目录下: ...
- day46 作业
# 班级表 create table class( cid int primary key auto_increment, caption char(16) ); # 学生表 create table ...
- alert(1) to win Part Ⅰ
alert(1) to win Adobe: function escape(s) { s = s.replace(/"/g, '\\"'); return '<script ...
- 细说php锁
bool flock ( int handle, int operation [, int &wouldblock] );flock() 操作的 handle 必须是一个已经打开的文件指针.o ...
- Burp Suite Repeater Module - 中继模块
目的:节省网页应用分析时间 目标对象:http://10.0.0.15/getboo/login.php 通过调整Request的参数,不断尝试,通过Response查看状态.从而节省在浏览器中操作的 ...
- dbca 建库报错 ORA-00600 解决办法
[oracle@tim1 ~]$ dbca## An unexpected error has been detected by HotSpot Virtual Machine:## SIGSEGV ...
- ATX 学习 (四)-atxserver2
ATXSERVER2 一.main()文件启动 1.首先通过parse_args返回一个Namespace作一些配置,登录页html在SimpleLoginHandler这个里边写着,2.接着通过db ...
- ATX学习(一)-atx-server
今天无意中发现了ATX手机设备管理平台,瞬间勾引起了我极大的兴趣,这里对学习过程中的情况做个记录. 1.搭建环境 先按照作者步骤搭建环境出来吧,哇,突然发现ATX搭建环境很方便(一会就搭建好了) ...
- Newbe.Claptrap 框架入门,第二步 —— 简单业务,清空购物车
接上一篇 Newbe.Claptrap 框架入门,第一步 —— 创建项目,实现简易购物车 ,我们继续要了解一下如何使用 Newbe.Claptrap 框架开发业务.通过本篇阅读,您便可以开始尝试使用 ...