带劲的计算几何【这一定是我WC之前开的最后一道计几!!!

每个点画个圆然后看一下交点 然后判断是多边形内还是多边形外

这个就是取圆上中点然后射线法

eps我1e-8才过 不知道为啥有的人说只能开1e-3

写了三天带劲= =

还有注意long double!附了一组数据~

  1. //Love and Freedom.
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #define inf 20021225
  7. #define ll long long
  8. #define eps 1e-8
  9. #define mxn 510
  10. #define db long double
  11. using namespace std;
  12. const db pi = acosl(-1.0);
  13. struct poi
  14. {
  15. db x,y;
  16. poi(){}
  17. poi(db _x,db _y){x=_x,y=_y;}
  18. };
  19. typedef poi vec;
  20. bool operator ==(vec a,vec b){return a.x==b.x&&a.y==b.y;}
  21. vec operator +(vec a,vec b){return vec(a.x+b.x,a.y+b.y);}
  22. vec operator -(vec a,vec b){return vec(a.x-b.x,a.y-b.y);}
  23. vec operator *(vec a,db b){return vec(a.x*b,a.y*b);}
  24. db cross(vec a,vec b){return a.x*b.y-a.y*b.x;}
  25. db value(vec a,vec b){return a.x*b.x+a.y*b.y;}
  26. db len(vec a){return a.x*a.x+a.y*a.y;}
  27. db ang(vec a){return atan2(a.y,a.x);}
  28. struct line
  29. {
  30. poi p; vec v; db ang;
  31. line(){}
  32. line(poi _p,poi _v)
  33. {
  34. p=_p; v=_v;
  35. ang = atan2(v.y,v.x);
  36. }
  37. }li[mxn];
  38. db cir[mxn]; int cnt,n,m;
  39. poi mid[mxn];
  40. db section(line a,line b)
  41. {
  42. db k = cross(a.v+a.p-b.p,a.p-b.p)/(cross(a.v+a.p-b.p,b.v)+cross(b.v,a.p-b.p));
  43. return k;
  44. }
  45. void get(line a,db r)
  46. {
  47. db c = - r*r + len(a.p);
  48. db aa = len(a.v);
  49. db b = 2.0*(a.v.x*a.p.x+a.v.y*a.p.y);
  50. db delta = b*b - 4.0 * aa * c;
  51. if(delta < 0) return ;
  52. delta = sqrt(delta);
  53. db k1 = (-b + delta)/(2.0*aa);
  54. if(abs(delta)<eps)
  55. {
  56. poi tmp = a.p+a.v*k1;
  57. if(k1>-eps && k1-1.0<eps) cir[++cnt] =atan2(tmp.y,tmp.x);
  58. return;
  59. }
  60. db k2 = (-b-delta)/(2.0*aa);
  61. poi tmp = a.p+a.v*k1;
  62. if(k1>-eps && k1-1.0<eps) cir[++cnt] = atan2(tmp.y,tmp.x);
  63. tmp = a.p+a.v*k2;
  64. if(k2>-eps && k2-1.0<eps) cir[++cnt] = atan2(tmp.y,tmp.x);
  65. }
  66. void put(poi a)
  67. {
  68. printf("p===%lf %lf\n",a.x,a.y);
  69. }
  70. void putl(line a)
  71. {
  72. printf("ls--------------\n");
  73. put(a.p); put(a.v); printf("%lf\n",a.ang);
  74. printf("le--------------\n");
  75. }
  76. bool between(line a,poi b)
  77. {
  78. int tmp=0;
  79. if(a.v.x <= 0.0)
  80. {
  81. if(b.x <= a.p.x && b.x >= a.p.x+a.v.x) tmp++;
  82. }
  83. else
  84. {
  85. if(b.x >= a.p.x && b.x <= a.p.x+a.v.x) tmp++;
  86. }
  87. if(a.v.y <= 0.0)
  88. {
  89. if(b.y <= a.p.y && b.y >= a.p.y+a.v.y) tmp++;
  90. }
  91. else
  92. {
  93. if(b.y >= a.p.y && b.y <= a.p.y+a.v.y) tmp++;
  94. }
  95. return tmp==2;
  96. }
  97. bool check(poi x)
  98. {
  99. for(int i=1;i<=m;i++)
  100. if(between(li[i],x) && abs(cross(x-li[i].p,li[i].v))<eps)
  101. return 0;
  102. int cer = 0;
  103. line tmp = line(x,poi(2794406.11,-2564800.0132));
  104. for(int i=1;i<=m;i++)
  105. {
  106. db w = section(tmp,li[i]);
  107. db ww = section(li[i],tmp);
  108. if( ww>1.0 || ww<0.0 || w>1.0 || w<0.0)
  109. continue;
  110. cer++;
  111. }
  112. if(cer&1) return 1;
  113. return 0;
  114. }
  115. bool cmp(poi a,poi b)
  116. {
  117. return ang(a) < ang(b) || (abs(ang(a)-ang(b))<eps&& cross(a,b)>eps);
  118. }
  119. bool same(poi a,poi b)
  120. {
  121. return abs(a.x-b.x)<eps && abs(a.y-b.y) <eps;
  122. }
  123. poi enemy[mxn],stk[mxn];
  124. db makecircle(int id,db r)
  125. {
  126. cnt = 0; db ans = 0.0;
  127. for(int i=1;i<=m;i++)
  128. get(li[i],r);
  129. if(!cnt)
  130. {
  131. if(check(enemy[id])) return 2*pi;
  132. return 0.0;
  133. }
  134. sort(cir+1,cir+cnt+1);
  135. int tot = cnt; cnt=1;
  136. for(int i=2;i<=tot;i++)
  137. if(abs(cir[i]-cir[i-1])>eps)
  138. cir[++cnt] = cir[i];
  139. cir[cnt+1] = cir[1] + 2*pi;
  140. for(int i=1;i<=cnt;i++)
  141. {
  142. db theta = (cir[i] + cir[i+1]); theta = theta/2.0;
  143. mid[i] = vec(r*cosl(theta),r*sinl(theta));
  144. }
  145. if(cnt==2)
  146. {
  147. if(check(mid[1]))
  148. {
  149. db ang = cir[2] - cir[1];
  150. ans += ang;
  151. }
  152. return ans;
  153. }
  154. for(int i=1;i<=cnt;i++)
  155. {
  156. if(check(mid[i]))
  157. {
  158. db ang = cir[i+1] - cir[i];
  159. ans += ang;
  160. }
  161. }
  162. return ans;
  163. }
  164. int main()
  165. {
  166. scanf("%d%d",&n,&m);
  167. for(int i=1;i<=n;i++) scanf("%Lf%Lf",&enemy[i].x,&enemy[i].y);
  168. for(int i=1;i<=m;i++)
  169. scanf("%Lf%Lf",&stk[i].x,&stk[i].y);
  170. for(int i=1;i<m;i++)
  171. li[i]=line(stk[i],stk[i+1]-stk[i]);
  172. li[m] = line(stk[m],stk[1]-stk[m]);
  173. db full,r,ans=0.0;
  174. for(int i=1;i<=n;i++)
  175. {
  176. r = sqrtl(len(enemy[i]));
  177. if(r<eps)
  178. {
  179. if(check(poi(0,0))) ans += 1.00000;
  180. continue;
  181. }
  182. full = 2*pi;
  183. ans += makecircle(i,r)/full;
  184. }
  185. printf("%.5Lf\n",ans);
  186. return 0;
  187. }
  188. /**
  189. 1 7
  190. 1 1
  191. 2 1
  192. -1 -1
  193. -1 1
  194. 1 1
  195. 1 2
  196. 3 1
  197. 2 -1
  198. */

LOJ6437 PKUSC2018 PKUSC的更多相关文章

  1. 【loj6437】 【PKUSC2018】 PKUSC 计算几何

    题目大意:给你一个m个点的简单多边形.对于每个点i∈[1,n],作一个以O点为原点且过点i的圆,求该圆在多边形内的圆弧长度/圆长. 其中n≤200,m≤500. 我们将n个点分开处理. 首先,我们要判 ...

  2. LOJ6437. 「PKUSC2018」PKUSC [计算几何]

    LOJ 思路 显然多边形旋转可以变成点旋转,不同的点的贡献可以分开计算. 然后就变成了要求一个圆在多边形内的弧长. 考虑把交点全都求出来,那么两个交点之间的状态显然是相同的,可以直接把圆弧上的中点的状 ...

  3. [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC

    [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC 试题描述 九条可怜是一个爱玩游戏的女孩子. 最近她在玩一个无双割草类的游戏,平面上有 \(n\) 个敌人,每一个敌人的坐标为 ...

  4. 【LOJ】#6437. 「PKUSC2018」PKUSC

    题解 我们把这个多边形三角形剖分了,和统计多边形面积一样 每个三角形有个点是原点,把原点所对应的角度算出来,记为theta 对于一个点,相当于半径为这个点到原点的一个圆,圆弧上的弧度为theta的一部 ...

  5. loj#6437. 「PKUSC2018」PKUSC(计算几何)

    题面 传送门 题解 计算几何的东西我好像都已经忘光了-- 首先我们可以把原问题转化为另一个等价的问题:对于每一个敌人,我们以原点为圆心,画一个经过该点的圆,把这个圆在多边形内部的圆弧的度数加入答案.求 ...

  6. [LOJ6437]PKUSC

    旋转多边形是没有前途的,我们考虑旋转敌人,那么答案就是所有人的可行区间长度之和除以$2\pi$ 首先对每个敌人找到那些旋转后会落到多边形上的角度,实际上就是圆和一些线段求交,解方程即可,注意判一下落在 ...

  7. 「PKUSC2018」PKUSC

    传送门 Solution  考虑求每个点的贡献 等价于一个以OA长为半径的圆心为原点的圆在多边形内的弧对应的角度/\(2\pi\) 求弧度可以利用三角剖分 在原点的点要特判,采用射线法就可以了 Cod ...

  8. LOJ#6437. 「PKUSC2018」PKUSC

    题面 题意转化为: 判断每个点所在的圆有多长的弧度角位于多边形内部. 然后就很暴力了. 每个点P,直接找到多边形和这个圆的所有交点,按照距离P的角度排序. 找交点,直接联立二元二次方程组.... 需要 ...

  9. 【LOJ6436】【PKUSC2018】神仙的游戏(NTT)

    [LOJ6436][PKUSC2018]神仙的游戏(NTT) 题面 LOJ 题解 看到\(zsy\)从\(PKUSC\)回来就秒掉了这种神仙题 吓得我也赶快看了看\(PKUSC\)都有些什么神仙题 然 ...

随机推荐

  1. web高拍仪图片上传

    公司引进高拍仪,想拍完照片点上传按钮直接上传图片.高拍仪接口能提供照片的本地路径,现在的问题是不用file控件选择,只有路径,不知道如何上传到服务器,求解决方案. 方法: 使用泽优Web图片上传控件( ...

  2. 状压DP常用操作

    1. 判断一个数字x二进制下第i位是不是等于1. 方法:if ( ( ( 1 << ( i - 1 ) ) & x ) > 0) 将1左移i-1位,相当于制造了一个只有第i位 ...

  3. CSS/CSS3常用的样式

    强制文本显示 让一段文字在固定宽度在一行显示,最后一个字符为省略标记(...),css样式如下 单行显示语法:white-space:nowrap; div{ white-space:nowrap; ...

  4. if和switch的选择结构

    1. Java中的if选择结构,包括以下形式. *基本if选择结构:可以处理一单一或组合条件的情况. *if-else选择结构:可以处理简单的条件分支情况. *多重if选择结构:可以处理连续区间的条件 ...

  5. sscanf sscanf_s使用

    #include<stdio.h> 定义函数 int sscanf (const char *str,const char * format,........); 函数说明  sscanf ...

  6. HDU6599:求本质不同的子串(回文串)长度及数量

    目录 hdu6599题意: manacher+后缀自动机+倍增 \(O(nlog(n))\) manacher+后缀数组+二分 \(O(nlog(n))\) 回文树(回文自动机) \(O(n)\) @ ...

  7. Codeforecs Round #425 D Misha, Grisha and Underground (倍增LCA)

    D. Misha, Grisha and Underground time limit per test 2 seconds memory limit per test 256 megabytes i ...

  8. HDU 6024 Building Shops (简单dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6024 题意:有n个room在一条直线上,需要这这些room里面建造商店,如果第i个room建造,则要总 ...

  9. Centos7开机自动启动服务和联网

    虚拟机设置选择NAT模式,默认情况下,Centos不是自动连接上网的,需要点击右上角,手动连接上网. 可以修改开机启动配置修改: 1. cd 到/etc/sysconfig/network-scrip ...

  10. DHCP服务器怎么设置怎么启动

    DHCP:动态主机配置协议,服务器用于为网络中的客户端自动分配IP地址.这种方法避免了由于手动配置IP地址导致的IP地址冲突问题,同时也减少了网络管理员的工作量. 工具/原料 在配置DHCP服务器时, ...