UVA 12537 Radiation 解题报告

比赛

题目

题意:

有一些房子和两个点。每次查询给出以两个点为圆心的圆的半径,在一个圆内的房子发一套防化服,所以相交部分的房子有两套,不在圆内的没有。将相交部分的房子多余的防化服发给没有的房子后,求还有多少房子没有防化服。

题解:

因为最后有防化服的房子只由一套防化服,所以就是求发出了多少套防化服。将每个房子到两个点的距离预处理出来,那么对于给定的半径二分就知道有多少房子在圆内。


//Time:238ms
//Memory:0KB
//Length:1312B
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define MAXN 200010
#define MAXM 100010
#define EPS 1e-8
int x[MAXN],y[MAXN];
double nee[2][MAXN];
int top[2];
double cal(int a,int b)
{
    return sqrt(1.0*(x[a]-x[b])*(x[a]-x[b])+1.0*(y[a]-y[b])*(y[a]-y[b]));
}
int bs(double arr[],int r,double key)
{
    int l=0,mid;
    while(l<r)
    {
        mid=(l+r+1)/2;
        if(arr[mid]>key+EPS)    r=mid-1;
        else    l=mid;
    }
    return l;
}
int main()
{
    //freopen("/home/moor/Code/input","r",stdin);
    int n,q,cnt=0;
    while(scanf("%d",&n)==1&&n)
    {
        printf("Case %d:\n",++cnt);
        for(int i=0;i<n;++i)
            scanf("%d%d",&x[i],&y[i]);
        scanf("%d%d",&x[n+1],&y[n+1]);
        scanf("%d%d",&x[n+2],&y[n+2]);
        for(int i=0;i<n;++i)
            nee[0][i]=cal(i,n+1),
            nee[1][i]=cal(i,n+2);
        nee[0][n]=0;
        nee[1][n]=0;
        sort(nee[0],nee[0]+n+1);
        sort(nee[1],nee[1]+n+1);
        scanf("%d",&q);
        for(int i=0;i<q;++i)
        {
            int r1,r2,n1,n2;
            scanf("%d%d",&r1,&r2);
            n1=bs(nee[0],n+1,r1);
            n2=bs(nee[1],n+1,r2);
            printf("%d\n",max(n-n1-n2,0));
        }
    }
    return 0;
}


你可能感兴趣的:(UVA 12537 Radiation 解题报告)