算给你的n个圆中最近的距离
(无圆相交)
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<set>
#include <math.h>
using namespace std;
set <int>tree;
set <int>::iterator iter;
struct Point
{
double x;
int id, flag;
} p1[100001], p2[100001];
int tot1, tot2;
struct Q
{
double x,y, r;
} q[50001];
int cmp(const void*p1, const void*p2)
{
struct Point*a1=(struct Point*)p1;
struct Point*a2=(struct Point*)p2;
if (a1->x<a2->x) return -1;
else if (a1->x==a2->x) return a2->flag-a1->flag;
else return 1;
}
int cmp1(const void*p1, const void*p2)
{
struct Q*a1=(struct Q*)p1;
struct Q*a2=(struct Q*)p2;
if (a1->y<a2->y)return -1;
else if (a1->y==a2->y)return 0;
else return 1;
}
double dis(double x1, double y1, double x2, double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
bool judge(int i, int j, double d)
{
if (dis(q[i].x, q[i].y, q[j].x, q[j].y)<=q[i].r+q[j].r+2.0*d)
return true;
return false;
}
bool insert(int v,double d)
{
iter = tree.insert(v).first;
if (iter != tree.begin())
{
if (judge(v, *--iter,d))
{
return true;
}
++iter;
}
if (++iter != tree.end())
{
if (judge(v, *iter,d))
{
return true;
}
}
return false;
}
bool remove(int v,double d)
{
iter = tree.find(v);
if (iter != tree.begin() && iter != --tree.end())
{
int a = *--iter;
++iter;
int b = *++iter;
if (judge(a, b,d))
{
return true;
}
}
tree.erase(v);
return false;
}
bool check(double d)
{
int i=1, j=1;
while (i<=tot1&&j<=tot2)
{
if (p1[i].x-d<=p2[j].x+d)
{
if (insert(p1[i++].id, d))
return true;
}
else
{
if (remove(p2[j++].id, d))
return true;
}
}
while (i<=tot1)
{
if (insert(p1[i++].id, d))
return true;
}
while (j<=tot2)
{
if (remove(p2[j++].id, d))
return true;
}
return false;
}
int main (void)
{
int cases, n, i;
scanf("%d",&cases);
while (cases--)
{
scanf("%d",&n);
tot1=tot2=0;
for (i=1; i<=n; i++)
scanf("%lf %lf %lf",&q[i].x,&q[i].y, &q[i].r);
qsort(q+1,n,sizeof(struct Q),cmp1);
for (i=1; i<=n; i++)
{
tot1++;
p1[tot1].x=q[i].x-q[i].r;
p1[tot1].id=i;
p1[tot1].flag=1;
tot2++;
p2[tot2].x=q[i].x+q[i].r;
p2[tot2].id=i;
p2[tot2].flag=-1;
}
qsort(p1+1,tot1,sizeof(struct Point),cmp);
qsort(p2+1,tot2,sizeof(struct Point),cmp);
double head=0.0, tail=dis(q[1].x,q[1].y,q[2].x,q[2].y)+1.0, mid;
while (tail-head>1e-8)
{
tree.clear();
mid=(head+tail)/2.0;
if (check(mid))
{
tail=mid;
}
else head=mid;
}
printf ("%.6lf\n",2.0*head);
}
return 0;
}