Sicily8544

一条从原点出发的射线,求所有和它相交的圆的相交弦的和的最大值。

从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);
	}
}


你可能感兴趣的:(Sicily8544)