题意:给二维平面上的n个点(n<=3000).选其中三个点做圆心,画三个半径相等且不相交的圆(可以相切),问半径最大可以是多少。
解法:可以转化为找一个最短边最长的三角形,圆心在三角形的三个顶点上。把n个点之间的连线长度从大到小排序,一条一条的加入集合中,如果当前当前线段的两个端点有两条在集合中且相交的线段,当前线段即为三角形的最短边。判断是否有交点可以用bitset简单粗暴的完成
关于bitset的用法
Member functions
-
(constructor)
- Construct bitset (public member function)
-
applicable operators
- Bitset operators (function )
Bit access :
-
operator[]
- Access bit (public member function)
Bit operations :
-
set
- Set bits (public member function)
-
reset
- Reset bits (public member function)
-
flip
- Flip bits (public member function)
Bitset operations :
-
to_ulong
- Convert to unsigned long integer (public member function)
-
to_string
- Convert to string (public member function)
-
count
- Count bits set (public member function)
-
size
- Return size (public member function)
-
test
- Return bit value (public member function)
-
any
- Test if any bit is set (public member function)
-
none
- Test if no bit is set (public member function)
//time:1479ms
//memory:107200 KB
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bitset>
#include <iostream>
#include <queue>
#define FI first
#define SE second
using namespace std;
const double EPS = 1e-8;
const int MAXN = 3005;
const int INF = 1111111111;
struct Point{
int x,y;
void input(){scanf("%d%d",&x,&y);}
}p[MAXN];
struct Node{
int u,v,d;
Node(){}
Node(int a,int b,int c):u(a),v(b),d(c){}
bool operator <(const Node&a)const
{
return d>a.d;
}
}seg[MAXN*MAXN];
bitset<MAXN> bit[MAXN],tmp;
int main()
{
//freopen("/home/qitaishui/code/in.txt","r",stdin);
int n,m=0,u,v,ans;
scanf("%d",&n);
for(int i = 0; i < n;i++)
p[i].input();
for(int i = 0; i < n; i++)
for(int j = i+1; j < n; j++)
seg[m++] = Node(i,j,(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
sort(seg,seg+m);
//cout<<"*\n";
for(int i = 0; i < m; i++)
{
u = seg[i].u,v = seg[i].v;
tmp = bit[u]&bit[v];
//cout<<u<<endl;
if(tmp.any())
{
ans = seg[i].d;
break;
}
bit[u].set(v);
bit[v].set(u);
}
//cout<<ans<<endl;
printf("%.10f\n",sqrt(1.0*ans)/2);
return 0;
}