题目链接:点击打开链接
题意:
给定n个圆
下面n行给出圆:(x,y,r)
且圆都在矩阵 [-200, -200] - [200,200] 内
有一个太阳,从坐标 [500, 0] 开始沿着圆 (0,0,500) 的弧走。
在任意时刻有一个值:
太阳和原点连成的线段与所有的圆相交,线段被圆所截得长度和就是这个时刻的值,求24小时内出现的最大的值是多少。
注意时间不是连续的,是离散的,一分钟计算一次。
所以枚举弧度即可。
判断时就用直线到点的距离判断。
但是实际上是线段,所以有些圆是不能算入答案的。如何判断这个圆是不是与线段相交。我们可以用2个向量的夹角是否<90°来判断
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <bits/stdc++.h> template <class T> inline bool rd(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x = -x; } if (x>9) pt(x / 10); putchar(x % 10 + '0'); } using namespace std; typedef long long ll; const double Pi = acos(-1.0); const double eps = 1e-10; const int N = 205; int n; struct node{ double x, y, r; }c[N]; double work(double hu, node q){ double len = sin(hu) * q.x - cos(hu) * q.y; if(len < 0) len = -len; if(len >= q.r) return 0.0; if(sin(hu)*q.y + (cos(hu)*q.x) > 0 ) return sqrt(q.r*q.r - len*len); else return 0.0; } int main(){ while (cin>>n, n){ for(int i = 1; i <= n; i++) { rd(c[i].x); rd(c[i].y); rd(c[i].r); } double ans = 0, dd = Pi/2.0/360.0; for(double hu = 0; hu <= Pi*2; hu += dd) { double tmp = 0; for(int j = 1; j <= n; j++) tmp += work(hu, c[j]); ans = max(ans, tmp); } printf("%.3f\n", ans * 2.0); } return 0; }