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\n",ans);
110     }
111 }

原文地址:https://www.cnblogs.com/qywhy/p/9739973.html

时间: 2024-08-25 00:30:53

Gym - 101915B Ali and Wi-Fi 计算几何 求两圆交点的相关文章

POJ 2546 &amp; ZOJ 1597 Circular Area(求两圆相交的面积 模板)

题目链接: POJ:http://poj.org/problem?id=2546 ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=597 Description Your task is to write a program, which, given two circles, calculates the area of their intersection with the accuracy of three di

hdu 3264 Open-air shopping malls 求两圆相交

对每个圆二分半径寻找可行的最小半径,然后取最小的一个半径. 对于两圆相交就只要求到两个扇形,然后减去两个全等三角形就行了. #include<cstdio> #include<iostream> #include<cmath> #include<algorithm> using namespace std; #define pi acos(-1.0) #define eps 1e-8 #define maxn 50 int n; struct point{

Fermat Point in Quadrangle(hdu 3694 求两直线交点

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3694 画几个图应该就可以知道凸四边形就是对角线交点 凹四边形就是凹进去的那个点 so 只要枚举四个点以及对角线交点 找个minn就可以 求两直线交点模板: double cross(double x1,double y1,double x2,double y2) { return x1*y2-x2*y1; } bool getcross(double x1,double y1,double x2,d

求两圆相交部分面积(C++)

已知两圆圆心坐标和半径,求相交部分面积: 1 #include <iostream> 2 using namespace std; 3 #include<cmath> 4 #include<stdio.h> 5 #define PI 3.141593 6 struct point//点 7 { 8 double x,y; 9 }; 10 struct circle//圆 11 { 12 point center; 13 double r; 14 }; 15 float

UVa 10674 (求两圆公切线) Tangents

题意: 给出两个圆的圆心坐标和半径,求这两个圆的公切线切点的坐标及对应线段长度.若两圆重合,有无数条公切线则输出-1. 输出是按照一定顺序输出的. 分析: 首先情况比较多,要一一判断,不要漏掉. 如果高中的那点老底还在的话,代码还是很好理解的. 1 //#define LOCAL 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #incl

[计算几何]求两个圆相交的交点坐标

很多人都说用角度误差大,今天学了不用角度的两种方法 https://blog.csdn.net/zx3517288/article/details/53326420 写个板子 方法一 方法二 原文地址:https://www.cnblogs.com/KonjakJuruo/p/9723156.html

hdu 5120 (求两圆相交的面积

题意:告诉你两个圆环,求圆环相交的面积. /* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set&

求两圆相交的面积

走自己的路,你会发现,在走的过程中你会收获很多 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <limits.h> #include <ctype.h> #include <string.h> #include <string> #include <algorithm> #include <iostream>

求两圆相交面积模板

#define PI 3.141592654 #define eps 1e-8 double getdis(int x1,int y1,int x2,int y2){ return sqrt((double)(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); } double getarea(int x1,int y1,double r1,int x2,int y2,double r2){ double d=getdis(x1,y1,x2,y2); if(r1+r2<d+eps)