LA6142 Radiation 二分查找
题目地址: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); } } }
posted on 2014-04-04 01:20 814jingqi的ACM 阅读(107) 评论(0) 编辑 收藏 举报