1. 程式人生 > >Gym - 101915B Ali and Wi-Fi 計算幾何 求兩圓交點

Gym - 101915B Ali and Wi-Fi 計算幾何 求兩圓交點

inline sin truct while con 最大 dot 都是 codeforce

題面

題意:給你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\n",ans); 110 } 111 }

Gym - 101915B Ali and Wi-Fi 計算幾何 求兩圓交點