题意:两个核电站对周围居民有辐射,影响的半径为R1,R2。核电站会对收到影响居民的分发装备。两个核电站的影响范围会有重叠,使有些居民有两套装备,这些居民会把设备给没有收到影响的居民。求,对于不同的半径R1,R2,没有设备的居民的人数。
思路:分别求出对每个居民到两个核电站距离,并排序。对于不同的半径,可以通过二分找到受到影响的居民数a,b。则n-a-b或0中的最大值就是结果。
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 200100
using namespace std;
typedef long long llint;
llint Y[MAXN], X[MAXN];
int P[MAXN][2];
int main()
{
//freopen("/home/acm/code/input.txt","r",stdin);
int n;
int iCase = 0;
while(cin>>n && n){
printf("Case %d:\n",++iCase);
for(int i=0; i<n; i++){
scanf("%d %d",&P[i][0], &P[i][1]);
}
int ax, ay, bx, by, q;
scanf("%d %d %d %d %d",&ax, &ay, &bx, &by, &q);
for(int i=0; i<n; i++){
llint d1x = ax - P[i][0];
llint d1y = ay - P[i][1];
llint d1 = d1x * d1x + d1y * d1y;
llint d2x = bx - P[i][0];
llint d2y = by - P[i][1];
llint d2 = d2x * d2x + d2y * d2y;
X[i] = d1;
Y[i] = d2;
}
sort(X, X+n);
sort(Y, Y+n);
//for(int i=0; i<n; i++) printf("%lld ",X[i]); puts("");
//for(int i=0; i<n; i++) printf("%lld ",Y[i]); puts("");
for(int i=0; i<q; i++){
llint R1, R2;
scanf("%lld %lld", &R1, &R2);
llint r1 = R1 * R1;
llint r2 = R2 * R2;
int a = n - (upper_bound(Y, Y+n, r2) - Y);
int b = upper_bound(X, X+n, r1) - X;
printf("%d\n",max(a-b,0));
}
}
}