GYM 101147 I.On the way to the park(水~)

来源:互联网 发布:华为海洋网络 面试 编辑:程序博客网 时间:2024/05/21 23:03

Description
给出一些小圆的圆心和半径,问一个圆心在x轴上,半径为R的大圆最多可以包含多少小圆
Input
第一行一整数T表示用例组数,每组用例首先输入两个整数n和R分别表示小圆数量和大圆半径,之后n行每行三个整数x,y,r表示一个小圆的圆心和半径(1<=n<=1e5,1<=R,r<=1e9,-1e9<=x,y<=1e9)
Output
输出大圆最多可以包含多少个小圆
Sample Input
2
3 5
0 0 1
4 0 2
10 0 1
4 3
0 1 1
0 -3 1
10 1 1
0 -4 2
Sample Output
3
1
Solution
求出每个小圆被包含需要的大圆半径横坐标取值范围,那么问题变成给出n个区间,问一个点最多能被多少区间覆盖,前缀和即可
Code

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 111111typedef pair<double,int>P;P p[2*maxn];int T,n,R;int main(){    freopen("walk.in","r",stdin);    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&R);        int res=0;        while(n--)        {            int x,y,r;            scanf("%d%d%d",&x,&y,&r);            if(r>R||abs(y)>R-r)continue;            double temp=sqrt(1.0*(R-r)*(R-r)-1.0*y*y);            p[res++]=P(1.0*x-temp,-r),p[res++]=P(1.0*x+temp,r);        }         sort(p,p+res);        ll ans=0,sum=0;        for(int i=0;i<res;i++)            sum+=p[i].second,ans=max(ans,-sum);        printf("%I64d\n",ans);    }    return 0;}
0 0
原创粉丝点击