题目大意:寻找两个圆的交集部分的点的个数c1,之后再寻找圆外面的点的个数c2。如果c2<c1则输出0,否则输出c2-c1
解题思路:
这个题目如果纯粹的暴力肯定是超时(别尝试了,我已经暴了N遍了,还是TLE)。关键还是优化算法,利用容斥原理+二分+排序
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#define maxn 200000+10
using namespace std;
#ifdef __int64
typedef __int64 LL;
#else
typedef long long LL;
#endif
int v[maxn][2];
double d1[maxn],d2[maxn];//保存每个点到两个圆的圆心的距离
int bs(double s[],int l,int h,int v)//二分查找,找出在圆内有多少个点
{
while(l<h)
{
int m=(l+h)>>1;
if(s[m]<=v)
{
l=m+1;
}
else
{
h=m;
}
}
return l;
}
int main()
{
int t,ncase=1;
while(scanf("%d",&t)&&t)
{
printf("Case %d:\n",ncase++);
for(int i=0;i<t;i++)
{
scanf("%d%d",&v[i][0],&v[i][1]);
}
int x1,y1,x2,y2,q;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&q);
for(int i=0;i<t;i++)
{
d1[i]=(double)sqrt((v[i][0]-x1)*(v[i][0]-x1)+(v[i][1]-y1)*(v[i][1]-y1));
d2[i]=(double)sqrt((v[i][0]-x2)*(v[i][0]-x2)+(v[i][1]-y2)*(v[i][1]-y2));
}
sort(d1,d1+t);
sort(d2,d2+t);
int c1,c2;
while(q--)
{
double a,b;
scanf("%lf%lf",&a,&b);
c1=bs(d1,0,t-1,a);//printf("c1=%d\n",c1);
c2=bs(d2,0,t-1,b);//printf("c2=%d\n",c2);
if(t-c1-c2<=0)
printf("0\n");
else
printf("%d\n",t-c1-c2);
}
}
return 0;
}