AsiaHatyai-2012 & LA 6144 - Radiation 二分搜索

     队内赛做的一道题..第一个关键是题意的把握...意思是每个nuclear plant可以在其R范围内发放保护装备..如果一个点被一个nuclear plant覆盖就拿一个装备..如果被两个覆盖拿两个装备..没有被任何的覆盖..领不到装备...拿了两个装备的把多余装备给没有装备的..问最终有多少人依然是没有装备的...

    由于两个nuclear plant以及所有的点都是固定的..所以可以先把所有点到plant A 的距离和plant B的距离算出来..排序分别存在两个数组中...对于当前询问R1,R2..可用二分查找快速得出有多少点被A覆盖..多少点被B覆盖...相加记为sum....那么总人数N-sum既是最后也拿不到装备的人数..注意..有可能N-sum<0..所以输出时max(0,N-sum)...      


Program:

//https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=585&page=show_problem&problem=4155
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#define ll long long 
#define oo 1000000001
#define MAXN  200002
using namespace std; 
struct node1
{
       int x,y;
}point[MAXN],a,b;  
int d1[MAXN],d2[MAXN],n;
int main()
{     
      // freopen("input.txt","r",stdin);   freopen("output.txt","w",stdout);  
       int i,q,R1,R2,l,r,mid,sum,t=0;
       while (~scanf("%d",&n))
       {
             if (!n) break;
             printf("Case %d:\n",++t);
             for (i=1;i<=n;i++) scanf("%d%d",&point[i].x,&point[i].y);
             scanf("%d%d%d%d%d",&a.x,&a.y,&b.x,&b.y,&q);
             for (i=1;i<=n;i++)
             {
                    d1[i]=(point[i].x-a.x)*(point[i].x-a.x)+(point[i].y-a.y)*(point[i].y-a.y);
                    d2[i]=(point[i].x-b.x)*(point[i].x-b.x)+(point[i].y-b.y)*(point[i].y-b.y);
             }
             sort(d1+1,d1+1+n);
             sort(d2+1,d2+1+n);
             while (q--)
             {
                    scanf("%d%d",&R1,&R2);
                    R1*=R1;  R2*=R2; 
                    l=0; r=n+1;
                    while (r-l>1)
                    {
                          mid=(r+l)/2;
                          if (d1[mid]<=R1) l=mid;
                            else r=mid;
                    }
                    sum=l;
                    l=0; r=n+1;
                    while (r-l>1)
                    {
                          mid=(r+l)/2;
                          if (d2[mid]<=R2) l=mid;
                            else r=mid;
                    }
                    sum+=l;
                    printf("%d\n",max(n-sum,0));
             }
       }
       return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值