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张信用卡的轮廓在上图中用实线标出 ...
随机推荐
- HTML5(五)Geolocation
HTML5 Geolocation 定位用户的位置 HTML5 Geolocation API 用于获得用户的地理位置. 鉴于该特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是不可用的. 注意 ...
- pycharm连接远程服务器(拉取版本)
pycharm连接远程服务器(拉取版本) 有这篇教程是因为,博主有两个办公地点,想着在办公地点A上传代码到服务器并调试,并在B时候可以拉取这份代码,并进行调试.因此有这篇拉取版本的博客,之前还有上传版 ...
- Docker Compose部署 EFK(Elasticsearch + Fluentd + Kibana)收集日志
简述 本文用于记录如何使用Docker Compose部署 EFK(Elasticsearch + Fluentd + Kibana) 收集Docker容器日志,使用EFK,可以无侵入代码,获得灵活, ...
- 测试必备工具之抓包神器 Charles 如何抓取 https 数据包?
之前发过一篇文章讲解了Charles抓包工具的基本使用(有需要的小伙伴可以去看上一篇文章), 讲的数据包主要是http协议,大家可以看到数据包并直接显示具体详细的内容: 但是如果抓到的是https的 ...
- [Mybatis]Mybatis常用操作
Mybatis是目前国内比较流行的ORM框架,特点是可以写灵活的SQL语句,非常适合中小企业的面向数据库开发. 本文总结自己开发过程中常用的Mybatis操作. 一.插入操作 主键自增插入单条 < ...
- 查看sudo的history:配置sudolog
sudo 权力很大,但责任更重大! We trust you have received the usual lecture from the local System Administrator. ...
- java 面向对象(三十六):泛型五 通配符
1.通配符的使用 /* 通配符的使用 通配符:? 类A是类B的父类,G<A>和G<B>是没关系的,二者共同的父类是:G<?> */ @Test public voi ...
- Ethical Hacking - GAINING ACCESS(15)
CLIENT SIDE ATTACKS Social Engineering Gather info about the user(s). Build a strategy based on the ...
- Python Ethical Hacking - WEB PENETRATION TESTING(2)
CRAWING DIRECTORIES Directories/folders inside the web root. Can contain files or other directories ...
- Redis 6.0 新特性 ACL 介绍
Redis 6.0 新特性 ACL 介绍 Intro 在 Redis 6.0 中引入了 ACL(Access Control List) 的支持,在此前的版本中 Redis 中是没有用户的概念的,其实 ...