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

Sample Output

21.66

HINT

本样例中的2张信用卡的轮廓在上图中用实线标出,如果视1.5707963268为

Pi/2(pi为圆周率),则其凸包的周长为16+4*sqrt(2)

【分析】

  乍一看还是不会做hh。

  把那个圆拿出来,做凸包,最后再加一个圆形的周长就好了。

  至于为什么,我还是看黄学长博客的,只能意会一下,不会证明,但是我觉得应该是把凸包向外平移然后凸多边形外角和等于360度,说明外面可以拼成一个完整的圆吧。

  所以一开始a-=2*r,b-=2*r。

  说一下旋转那部分,傻傻地画图搞了很久,用向量就会很方便。

  设a和b的夹角是y,要旋转的角是x。

  假设中心点在原点,最后再平移。一开始不旋转的时候是(b/2,a/2)

  设r*r=a*a+b*b

  新点(r*cos(x+y),r*sin(x+y)) -> (r*cosx*cosb-r*sinx*sinb,r*sinx*sinb+r*cosx*sinb) -> (b/2*cosx-a/2*sinx)

  其他三个点类似。

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<cmath>
  7. using namespace std;
  8. #define Maxn 400010
  9.  
  10. const double eps=0.00001;
  11. const double pi=3.14159265;
  12.  
  13. struct P
  14. {
  15. double x,y;
  16. }t[Maxn],w[Maxn];
  17. int len,wl;
  18. double a,b,r;
  19.  
  20. P operator - (P a,P b)
  21. {
  22. P tt;
  23. tt.x=a.x-b.x;tt.y=a.y-b.y;
  24. return tt;
  25. }
  26.  
  27. /*P rot(P x,double d,double c)
  28. {
  29. P nw;
  30. nw.x=x.x+d*cos(c);
  31. nw.y=x.y+d*sin(c);
  32. return nw;
  33. }*/
  34.  
  35. P rot(double x,double y,P nw,double c)
  36. {
  37. P ans;
  38. ans.x=x+nw.x*cos(c)-nw.y*sin(c);
  39. ans.y=y+nw.x*sin(c)+nw.y*cos(c);
  40. return ans;
  41. }
  42.  
  43. void make_p(double x,double y,double c)
  44. {
  45. P nw;
  46. nw.x=b/,nw.y=a/; t[++len]=rot(x,y,nw,c);
  47. nw.x=-b/,nw.y=a/; t[++len]=rot(x,y,nw,c);
  48. nw.x=b/,nw.y=-a/; t[++len]=rot(x,y,nw,c);
  49. nw.x=-b/,nw.y=-a/; t[++len]=rot(x,y,nw,c);
  50. /*for(int k=0;k<4;k++)
  51. {
  52. nw.x=x;nw.y=y;
  53. P now=rot(nw,b/2,k*pi/2+c);
  54. t[++len]=rot(now,a/2,(k+1)*pi/2+c);
  55. double tt;
  56. tt=a;a=b;b=tt;
  57. }*/
  58. }
  59.  
  60. double myabs(double x) {return x>?x:-x;}
  61.  
  62. int fbs(double x)
  63. {
  64. if(myabs(x)<=eps) return ;
  65. else return x>?:-;
  66. }
  67.  
  68. bool cmp(P x,P y) {return fbs(x.x-y.x)==?(x.y<y.y):(x.x<y.x);}
  69. double Dot(P x,P y) {return x.x*y.x+x.y*y.y;}
  70. double Cross(P x,P y) {return x.x*y.y-x.y*y.x;}
  71.  
  72. void chull()
  73. {
  74. sort(t+,t++len,cmp);
  75. wl=;
  76. for(int i=;i<=len;i++)
  77. {
  78. while(wl>&&Cross(w[wl]-w[wl-],t[i]-w[wl])<=) wl--;
  79. w[++wl]=t[i];
  80. }
  81. int k=wl;
  82. for(int i=len-;i>=;i--)
  83. {
  84. while(wl>k&&Cross(w[wl]-w[wl-],t[i]-w[wl])<=) wl--;
  85. w[++wl]=t[i];
  86. }
  87. wl--;
  88. }
  89.  
  90. double get_length()
  91. {
  92. double ans=;
  93. for(int i=;i<wl;i++)
  94. {
  95. ans+=sqrt(Dot(w[i]-w[i+],w[i]-w[i+]));
  96. }
  97. ans+=sqrt(Dot(w[wl]-w[],w[wl]-w[]));
  98. return ans;
  99. }
  100.  
  101. int main()
  102. {
  103. int n;
  104. scanf("%d",&n);
  105. scanf("%lf%lf%lf",&a,&b,&r);a-=*r;b-=*r;
  106. len=;
  107. for(int i=;i<=n;i++)
  108. {
  109. double x,y,c;
  110. scanf("%lf%lf%lf",&x,&y,&c);
  111. make_p(x,y,c);
  112. }
  113. chull();
  114. double ans=get_length();
  115. ans+=*r*pi;
  116. printf("%.2lf\n",ans);
  117. return ;
  118. }

2016-12-13 18:38:01

【BZOJ 2829】 2829: 信用卡凸包 (凸包)的更多相关文章

  1. BZOJ2829信用卡凸包——凸包

    题目描述 输入 输出 样例输入 2 6.0 2.0 0.0 0.0 0.0 0.0 2.0 -2.0 1.5707963268 样例输出 21.66 提示 本样例中的2张信用卡的轮廓在上图中用实线标出 ...

  2. luogu P3829 [SHOI2012]信用卡凸包 凸包 点的旋转

    LINK:信用卡凸包 当 R==0的时候显然是一个点的旋转 之后再求凸包即可. 这里先说点如何旋转 如果是根据原点旋转的话 经过一个繁杂的推导可以得到一个矩阵. [cosw,-sinw] [sinw, ...

  3. BZOJ 2388: 旅行规划 [分块 凸包 等差数列]

    传送门 题意: 区间加和询问一段区间内整体前缀和的最大值 刚才还在想做完这道题做一道区间加等差数列结果发现这道就是.... 唯一的不同在于前缀和一段区间加上等差数列后,区间后面也要加上一个常数!!! ...

  4. 【bzoj2829】信用卡凸包 凸包

    题目描述 输入 输出 样例输入 26.0 2.0 0.00.0 0.0 0.02.0 -2.0 1.5707963268 样例输出 21.66 题解 凸包 傻逼题,答案显然为:所有圆心构成的凸包周长+ ...

  5. bzoj 2300: [HAOI2011]防线修建 凸包

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2300 题解 这道题让我们维护一个支持动态删除点的上凸壳 并且告诉了我们三个一定不会被删除 ...

  6. bzoj 1069: [SCOI2007]最大土地面积 凸包+旋转卡壳

    题目大意: 二维平面有N个点,选择其中的任意四个点使这四个点围成的多边形面积最大 题解: 很容易发现这四个点一定在凸包上 所以我们枚举一条边再旋转卡壳确定另外的两个点即可 旋(xuan2)转(zhua ...

  7. bzoj 2961 共点圆 cdq+凸包+三分

    题目大意 两种操作 1)插入一个过原点的圆 2)询问一个点是否在所有的圆中 分析 在圆中则在半径范围内 设圆心 \(x,y\) 查询点\(x_0,y_0\) 则\(\sqrt{(x-x_0)^2+(y ...

  8. bzoj 2087: [Poi2010]Sheep【凸包+极角排序+dp】

    首先处理处理出来哪些边能连--能把羊分成两个偶数部分的,实现是在凸包上枚举极点,极角排序,枚举凸包上点对判断两边羊的个数的奇偶即可,设可以连边为v[i][j]=1 然后设f[i][j]为从i到j个凸包 ...

  9. bzoj 1027: [JSOI2007]合金【凸包+Floyd】

    参考:https://www.cnblogs.com/zhuohan123/p/3237246.html 因为一c可以由1-a-b得出,所以删掉c,把a,b抽象成二维平面上的点.首先考虑一个客户需求能 ...

  10. hdu4273Rescue(三维凸包重心)

    链接 模板题已不叫题.. 三维凸包+凸包重心+点到平面距离(体积/点积)  体积-->混合积(先点乘再叉乘) #include <iostream> #include<cstd ...

随机推荐

  1. 如何获取Window

    [[UIApplication sharedApplication].delegate window]

  2. 日常bug及解决方法记录

    工作中经常会遇到一些Bug,时间长了有时候就忘记了,这样不好. 特地在这加一个随笔,把以后出现的有价值一点的bug记录在这里,提醒自己,也可以给刚入门的同学一些参考,避免这些坑. 1:界面已经销毁,代 ...

  3. jquery实现2级联动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. javascript笔记——图片大小检测

    <html> <head> <script type="text/javascript"> var isIE = /msie/i.test(na ...

  5. xamarin android——数据绑定到控件(四)

    本文为通过自定义列表适配器定义ListView,以上文为基础,基于ListActivity. 定义列表项布局,包含一个图片显示,标题和描述 <LinearLayout xmlns:android ...

  6. 利用LRUMap 设计缓存

    上下文缓存,即将一些常用的数据至于一个缓存集合中,当需要获取这些数据的时候,直接从缓存中读取,而不必每次都从数据库读取,以此提高效率. 其原理类似Apache Commons Collections  ...

  7. java 读写锁

    http://tutorials.jenkov.com/java-concurrency/read-write-locks.html 翻译 读写锁比LOCK的实现更复杂,想象有一个应用程序能读和写一些 ...

  8. Spring多数据源的动态切换

    Spring多数据源的动态切换 目前很多项目中只能配置单个数据源,那么如果有多个数据源肿么办?Spring提供了一个抽象类AbstractRoutingDataSource,为我们很方便的解决了这个问 ...

  9. SQL Server数据库连接类SQLHelper.cs

    using System; using System.Collections.Generic; using System.Text; using System.Configuration; using ...

  10. JS焦点图,JS 多个页面放多个焦点图

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...