一条从原点出发的射线,求所有和它相交的圆的相交弦的和的最大值。
从Y轴开始共24*60个时刻,旋转一周。
每个时刻转的角度为360°/(24*60)。
直接一个一个枚举判断即可。
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <vector> #include <cmath> #include <algorithm> using namespace std; struct circle { double x,y,r; }; struct circle c[205]; int n; double cal(double k,double angle) { int i; double ans=0; double pi=acos(-1); for (i=0;i<n;i++) { double length2=(k*c[i].x-c[i].y)*(k*c[i].x-c[i].y)/(k*k+1); double xx=(c[i].x+k*c[i].y)/(k*k+1); double yy=k*xx; if (length2<=c[i].r*c[i].r) { if (angle>pi/2 && angle<=pi && xx<0 && yy>=0) ans+=sqrt(c[i].r*c[i].r-length2)*2; else if (angle>pi && angle<3*pi/2 && xx<0 && yy<0) ans+=sqrt(c[i].r*c[i].r-length2)*2; else if (angle>3*pi/2 && angle<=2*pi && xx>0 && yy<=0) ans+=sqrt(c[i].r*c[i].r-length2)*2; else if (angle>2*pi && xx>0 && yy>0) ans+=sqrt(c[i].r*c[i].r-length2)*2; } } return ans; } int main() { while (1) { int i; scanf("%d",&n); if (!n) break; for (i=0;i<n;i++) scanf("%lf%lf%lf",&c[i].x,&c[i].y,&c[i].r); double per=2*acos(-1)/(24*60); double maxn=0; double ans=0; for (i=0;i<n;i++) { if (c[i].r>fabs(c[i].x) && c[i].y>0) ans+=sqrt(c[i].r*c[i].r-c[i].x*c[i].x)*2; } maxn=ans; ans=0; for (i=0;i<n;i++) { if (c[i].r>fabs(c[i].x) && c[i].y<0) ans+=sqrt(c[i].r*c[i].r-c[i].x*c[i].x)*2; } if (ans>maxn) maxn=ans; double angle=acos(-1)/2; for (i=1;i<=24*60-1;i++) { angle+=per; double k=tan(angle); double temp=cal(k,angle); if (temp>maxn) maxn=temp; } printf("%.3lf\n",maxn); } }