Gym - 101915B Ali and Wi-Fi 计算几何 求两圆交点
Posted qywhy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym - 101915B Ali and Wi-Fi 计算几何 求两圆交点相关的知识,希望对你有一定的参考价值。
题意:给你n个圆,每个圆有一个权值,你可以选择一个点,可以获得覆盖这个点的圆中,权值最大的m个的权值,问最多权值是多少
题解:好像是叙利亚的题....我们画画图就知道,我们要找的就是圆与圆交的那部分里面的点,我们再仔细看看,
2个圆的交点一定在啊!
别急啊,两个圆包含了,都是交点,取哪呢?当然小圆圆心就够了啊(圆又不多,写的时候直接把所有的圆心都丢进去了)
然后枚举判断每个点有没有被在m个圆中就行了,这里维护最大的m个,用个堆就好了
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long double ld; 4 const ld eps = 1e-10; 5 int dcmp(ld x) 6 { 7 if(fabs(x) < eps) return 0; 8 return x < 0 ? -1 : 1; 9 } 10 ld sqr(ld x) { return x * x; } 11 struct Point 12 { 13 ld x, y; 14 Point(ld x = 0, ld y = 0):x(x), y(y) {} 15 }; 16 Point operator - (const Point& A, const Point& B) 17 { 18 return Point(A.x - B.x, A.y - B.y); 19 } 20 bool operator == (const Point& A, const Point& B) 21 { 22 return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.x) == 0; 23 } 24 ld Dot(const Point& A, const Point& B) 25 { 26 return A.x * B.x + A.y * B.y; 27 } 28 ld dis(Point a,Point b) 29 { 30 return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)); 31 } 32 ld Length(const Point& A) { return sqrt(Dot(A, A)); } 33 ld angle(Point v) { return atan2(v.y, v.x); } 34 struct Circle 35 { 36 Point c; 37 ld r,v; 38 Circle() {} 39 Circle(Point c, ld r):c(c), r(r) {} 40 inline Point point(double a) 41 { 42 return Point(c.x+cos(a)*r, c.y+sin(a)*r); 43 } 44 }a[105]; 45 int getCircleCircleIntersection(Circle C1, Circle C2,Point &t1,Point &t2) 46 { 47 ld d = Length(C1.c - C2.c); 48 if(dcmp(d) == 0) 49 { 50 if(dcmp(C1.r - C2.r) == 0) return -1; 51 return 0; 52 } 53 if(dcmp(C1.r + C2.r - d) < 0) return 0; 54 if(dcmp(fabs(C1.r-C2.r) - d) > 0) return 0; 55 ld a = angle(C2.c - C1.c); 56 ld da = acos((C1.r*C1.r + d*d - C2.r*C2.r) / (2*C1.r*d)); 57 Point p1 = C1.point(a-da), p2 = C1.point(a+da); 58 t1=p1; 59 if(p1 == p2) return 1; 60 t2=p2; 61 return 2; 62 } 63 Point jd[20000]; 64 ld ans,sum; 65 int n,m,T,tot; 66 priority_queue<int,vector<int>,greater<int> >q; 67 int main() 68 { 69 scanf("%d",&T); 70 while (T--) 71 { 72 tot=0; 73 ans=0; 74 scanf("%d%d",&n,&m); 75 for (int i=1;i<=n;i++) scanf("%Lf%Lf%Lf%Lf",&a[i].c.x,&a[i].c.y,&a[i].r,&a[i].v); 76 for (int i=1;i<=n;i++) 77 for (int j=i+1;j<=n;j++) 78 { 79 Point t1,t2; 80 int why=getCircleCircleIntersection(a[i],a[j],t1,t2); 81 if (why==1) 82 { 83 tot++; 84 jd[tot]=t1; 85 }else 86 if (why==2) 87 { 88 tot++;jd[tot]=t1; 89 tot++;jd[tot]=t2; 90 } 91 } 92 for (int i=1;i<=n;i++) 93 { 94 tot++; 95 jd[tot]=a[i].c; 96 } 97 for (int i=1;i<=tot;i++) 98 { 99 for (int j=1;j<=n;j++) 100 if (dcmp(dis(jd[i],a[j].c)-a[j].r)<=0) 101 { 102 q.push(a[j].v); 103 if ((int)q.size()>m) q.pop(); 104 } 105 sum=0; 106 while (!q.empty()) sum+=q.top(),q.pop(); 107 ans=max(ans,sum); 108 } 109 printf("%.Lf ",ans); 110 } 111 }
以上是关于Gym - 101915B Ali and Wi-Fi 计算几何 求两圆交点的主要内容,如果未能解决你的问题,请参考以下文章
Gym 100507H - Pair: normal and paranormal
Gym - 100923APor Costel and Azerah(思维水题)