题目地址:LA6142
题意是:同时处在两个辐射区的有两套,同时不在的点没有,现在问如果把有两套装备的人给一套个没有装备的人,最后有多少人没有装备?
设A为在R1内的点的集合,B 同理,那么如果不在辐射区的很少,应该是0! 不是负数,所以if(ans<0) ans=0;
然后是集合操作: |非A交非B|-|A交B|=n-|A|-|B|+|A交B|-|A交B|=n-|A|-|B| ;
然后输入一个r1,r2就进行一次二分查找就好了
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long inta;
struct Pointa
{
inta x;
inta y;
inta dis1;
inta dis2;
Pointa (inta x,inta y,inta dis1,inta dis2) :x(x),y(y),dis1(dis1),dis2(dis2){}
Pointa (){}
};
Pointa p[200010];
Pointa pp[200010];
bool cmp1(Pointa A,Pointa B)
{
if(A.dis1<B.dis1) return 1;
else return 0;
}
bool cmp2(Pointa A,Pointa B)
{
if(A.dis2<B.dis2) return 1;
else return 0;
}
inta min(inta a,inta b)
{
return a<b?a:b;
}
inta max(inta a,inta b)
{
return a>b?a:b;
}
int main()
{
int cas=0;
inta n;
inta ax,ay,bx,by,q;
while(cin>>n)
{
if(!n) break;
for(inta i=0;i<n;i++)
scanf("%lld%lld",&p[i].x,&p[i].y);
scanf("%lld%lld%lld%lld%lld",&ax,&ay,&bx,&by,&q);
for(inta i=0;i<n;i++)
{
p[i].dis1=(p[i].x-ax)*(p[i].x-ax)+(p[i].y-ay)*(p[i].y-ay);
p[i].dis2=(p[i].x-bx)*(p[i].x-bx)+(p[i].y-by)*(p[i].y-by);
}
for(inta i=0;i<n;i++)
{
pp[i].x=p[i].x;
pp[i].y=p[i].y;
pp[i].dis1=p[i].dis2;
pp[i].dis2=p[i].dis2;
}
sort(p, p+n,cmp1);
sort(pp,pp+n,cmp2);
inta r1, r2;
//cout<<"Case "<<++cas<<":"<<endl;
printf("Case %d:\n",++cas);
while(q--)
{
scanf("%lld%lld",&r1,&r2);
r1=r1*r1;
r2=r2*r2;
Pointa p1(0,0,r1,0);
Pointa p2(0,0,0,r2);
Pointa p3(0,0,0,0);
inta withinR1=upper_bound(p, p+n,p1,cmp1)-lower_bound(p, p+n,p3,cmp1);
inta withinR2=upper_bound(pp, pp+n,p2,cmp2)-lower_bound(pp, pp+n,p3,cmp2);
inta ans=n-withinR1-withinR2;
if(ans<0) ans=0;
printf("%lld\n",ans);
}
}
}