版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42391248/article/details/84722684
将圆的问题变换成线段的问题,按照左端点排序,如果i的右端点小于j的左端点,那么j之后的圆都和他相离。
用lower_bound二分查找找到j,否则会超时。
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int l,r,x,R;
}a[50005];
bool cmp(node aa,node bb)
{
if(aa.l==bb.l)
return aa.r<bb.r;
return aa.l<bb.l;
}
int main()
{
int n;
cin>>n;
int i,j;
for(i=0;i<n;i++)
{
cin>>a[i].x>>a[i].R;
a[i].l=a[i].x-a[i].R;
a[i].r=a[i].x+a[i].R;
}
sort(a,a+n,cmp);
int s[50005];
for(i=0;i<n;i++)
s[i]=a[i].l;
// for(i=0;i<n;i++)
// cout<<a[i].l<<" "<<a[i].r<<endl;
int ans=0;
for(i=0;i<n;i++)
{
int m=lower_bound(s,s+n,a[i].r)-s;
if(a[m].l<=a[i].r) m++;
if(m>=n) continue;
ans+=n-m;
// cout<<i<<" "<<m<<endl;
}
cout<<ans<<endl;
}