题意:
有一些房子和两个点。每次查询给出以两个点为圆心的圆的半径,在一个圆内的房子发一套防化服,所以相交部分的房子有两套,不在圆内的没有。将相交部分的房子多余的防化服发给没有的房子后,求还有多少房子没有防化服。
题解:
因为最后有防化服的房子只由一套防化服,所以就是求发出了多少套防化服。将每个房子到两个点的距离预处理出来,那么对于给定的半径二分就知道有多少房子在圆内。
//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;
}