题目链接:
UVALive 6092 - Catching Shade in Flatland
题意:
给 n 个都在
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
const int MAX_N = 210;
const double eps = 1e-8;
const double pi = acos(-1.0);int sgn(double x)
{if(fabs(x) <= eps) return 0;else if(x > eps) return 1;else return -1;
}struct Point{double x, y;Point() {}Point(double _x, double _y) : x(_x), y(_y) {}bool operator == (const Point& rhs) const {return sgn(x - rhs.x) == 0 && sgn(y - rhs.y) == 0;}bool operator < (const Point& rhs) const {return sgn(x - rhs.x) == 0 ? sgn(y - rhs.y) < 0 : x < rhs.x;}Point operator - (const Point& rhs) const {return Point(x - rhs.x, y - rhs.y);}Point operator + (const Point& rhs) const {return Point(x + rhs.x, y + rhs.y);}Point operator * (const double d) const {return Point(x * d, y * d);}Point operator / (const double d) const {return Point(x / d, y / d);}double dot(const Point& rhs) const { //点积return x * rhs.x + y * rhs.y;}double cross(const Point& rhs) const { //叉积return x * rhs.y - y * rhs.x;}double dis(const Point& rhs) const { //两点距离return hypot(x - rhs.x, y - rhs.y);}double len(){ //长度return hypot(x, y);}};struct Line{Point s, e;Line() {}Line(const Point& _s, const Point& _e) : s(_s), e(_e) {}bool operator == (const Line& rhs) const {return s == rhs.s && e == rhs.e;}double length() const { //线段长度return s.dis(e);}bool point_on_seg(const Point& rhs) const { //点在线段上的判断return sgn((rhs - s).cross(e - s)) == 0 && sgn((rhs - s).dot(rhs - e)) <= 0;}double point_to_line_dis(const Point& rhs) const{ //点到直线的距离return fabs((rhs - s).cross(e - s)) / length();}double point_to_seg_dis(const Point& rhs) const { //点到线段的距离if(sgn((rhs - s).dot(e - s)) < 0 || sgn((rhs - e).dot(s - e)) < 0){return min(rhs.dis(s), rhs.dis(e));}else return point_to_line_dis(rhs);}
};struct Circle{double x, y, r;Circle() {}Circle(double _x, double _y, double _r) : x(_x), y(_y), r(_r) {}
}circle[MAX_N];Line ray;
Point inter1, inter2, ori = Point(0.0, 0.0), sun;inline double check()
{double len = inter1.dis(inter2);if(ray.point_on_seg(inter1) && ray.point_on_seg(inter2)) return len;else if(ray.point_on_seg(inter1)) return ori.dis(inter1);else if(ray.point_on_seg(inter2)) return ori.dis(inter2);else return 0.0;
}int main()
{int n;double R = 500.0, angle = pi / 720.0;//printf("angle * 1440 = %.10lf 2 * pi = %.10lf\n", angle * 1440, 2 * pi);while(~scanf("%d", &n) && n) {for(int i = 0; i < n; ++i) {scanf("%lf%lf%lf", &circle[i].x, &circle[i].y, &circle[i].r);}double ans = 0.0, tmp;for(int i = 0; i < 1440; ++i) {double x0 = R * sin(angle * i), y0 = R * cos(angle * i);sun = Point(x0, y0);ray = Line(ori, sun);tmp = 0.0;if(sgn(x0) == 0) continue;for(int j = 0; j < n; ++j) {double x = circle[j].x, y = circle[j].y, r = circle[j].r;Point center = Point(x, y);if(sgn(ray.point_to_line_dis(center) - r) >= 0) continue;double a = R * R, b = 2 * x * x0 * x0 + 2 * x0 * y0 * y, c = x0 * x0 * (x * x + y * y - r * r);double tt = sqrt(b * b - 4 * a * c);double x1 = (b - tt) / 2.0 / a, x2 = (b + tt) / 2.0 / a;inter1 = Point(x1, x1 * y0 / x0), inter2 = Point(x2, x2 * y0 / x0);tmp += check();}//if(tmp > ans) printf("i = %d i * angel = %.3lf tmp = %.3lf ans = %.3lf\n", i, angle * i, tmp, ans);ans = max(ans, tmp);}//右半横轴上sun = Point(500.0, 0.0);tmp = 0.0;for(int i = 0; i < n; ++i) {double x = circle[i].x, y = circle[i].y, r = circle[i].r;if(sgn(r - fabs(y)) <= 0) continue;double tt = sqrt(r * r - y * y);double x1 = x - tt, x2 = x + tt;inter1 = Point(x1, 0.0), inter2 = Point(x2, 0.0);tmp += check();}//if(tmp > ans) printf("tmp = %.3lf ans = %.3lf\n", tmp, ans);ans = max(ans, tmp);//左半横轴sun = Point(-500.0, 0.0);tmp = 0.0;for(int i = 0; i < n; ++i) {double x = circle[i].x, y = circle[i].y, r = circle[i].r;if(sgn(r - fabs(y)) <= 0) continue;double tt = sqrt(r * r - y * y);double x1 = x - tt, x2 = x + tt;inter1 = Point(x1, 0.0), inter2 = Point(x2, 0.0);tmp += check();}//if(tmp > ans) printf("tmp = %.3lf ans = %.3lf\n", tmp, ans);ans = max(ans, tmp);printf("%.3lf\n", ans);}return 0;
}