当前位置: 首页 > 工具软件 > Goddess > 使用案例 >

【HDU4855】Goddess——区间+三分

仲孙华奥
2023-12-01
Time Limit: 20000/10000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)

Special Judge

Problem Description

Goddess used to be a good friend of Jitui, but Jitui has always been busy solving algorithm problems which makes Goddess very upset. In order to punish Jitui, Goddess will send N spaceships to attack Jitui’s LAB (Lost Algorithm Base). Jitui’s LAB is going to use laser weapons to destroy some of the spaceships.
The whole space can be seen as a two-dimensional coordinate system. Jitui’s LAB is a single point located at (0, 0). Each spaceship can be considered as a circle with center at (xi, yi) and radius ri. Laser weapon can be viewed as a ray starting from (0, 0), and in a direction chosen by Jitui. For each spaceship, the sum of length of segments that covered by the ray is the total damage made by the laser. Note that spaceships may overlap, which means the length that the laser weapon covers each spaceship may be calculated more than once. Jitui wants you to help him calculate the maximum damage he can make.
The number of spaceships N will not exceed 200. All centers of spaceships are guaranteed to be in the square with the left-down point at (-1000, -1000) and the right-up point at (1000, 1000). No spaceship will cover the point of (0, 0).

Input

There are several test cases. Please process till EOF.
For each case, the first line contains a number N that denotes the number of spaceships. Then next N lines, i-th line contains three numbers x, y, r denotes the coordinate of the center (x and y) and radius (r) of the i-th spaceship.

Output

For each case, output the maximized damage made by Jitui’s laser weapon.
Your output will be considered correct if within an absolute error less than 10-6.

Sample Input

1
50 0 10
2
30 0 10
60 20 20

Sample Output

20.0000000000
53.0366762251

Source

2014西安全国邀请赛
对于每一个圆,我们会发现它是符合凸函数的性质的,那么几个凸函数相加也是凸函数,对于凸函数的极值我们可以通过三分的形式得到。我们将每个圆我们可以得到每个切线和过圆心的射线。我们通过三分得到最大值。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 220;
const double Pi = acos(-1.0);
const double eps = 1e-13;
struct node {
    double x,y,r;
}circ[maxn];
int n,m;
double ang[maxn*10];
double Getdistances(double x,double y) {return sqrt(x*x+y*y);}
int dbcmp(double s) {
    return s>eps?1:(s<-eps?-1:0);
}
double cal(double Ang) {
    double ans = 0;
    for(int i = 0;i<n;i++) {
        double x = circ[i].x*cos(Ang)+circ[i].y*sin(Ang);
        double y = fabs(circ[i].x*sin(Ang)-circ[i].y*cos(Ang));
        if(dbcmp(y-circ[i].r)<0 && dbcmp(x)>0) {
            ans += 2.0*sqrt(circ[i].r*circ[i].r-y*y);
        }
    }
    return ans;
}
int main(){
    while(~scanf("%d",&n)) {
        for(int i = 0;i<n;i++) scanf("%lf %lf %lf",&circ[i].x,&circ[i].y,&circ[i].r);
        m  =  0;
        ang[m++] = Pi; ang[m++] = -Pi;
        for(int i = 0;i<n;i++) {
            double acen = atan2(circ[i].y,circ[i].x);
            double dist = Getdistances(circ[i].x,circ[i].y);
            double delta = asin(circ[i].r/dist);
            double ang1 = acen-delta , ang2 = acen + delta;
            if(dbcmp(ang1+Pi)<0) ang1+=2*Pi;
            if(dbcmp(ang2-Pi)>0) ang2-=2*Pi;
            ang[m++] = acen;
            ang[m++] = ang1;
            ang[m++] = ang2;
        }
        sort(ang,ang+m);
        m = unique(ang,ang+m)-ang;
        double ans = 0;
        for(int i = 0;i< m - 1;i++) {
            double l = ang[i];
            double r = ang[i+1];
            double ant = 0;
            while(l<=r) {
                double cl = l+(r-l)/3;
                double cr = l+ 2*(r-l)/3;
                double antl = cal(cl);
                double antr = cal(cr);
                if(dbcmp(antl-antr)>=0) {
                    ant = antl;
                    r = cr-eps;
                }
                else {
                    ant = antr;
                    l = cl+eps;
                }
            }
            if(dbcmp(ans-ant)<0) ans = ant;
        }
        printf("%.10f\n",ans);
    }
    return 0;
}
 类似资料: