题目链接:[Codeforces Round 194 (Div. 1)] Summer Earnings

代码&思路:

#include<iostream>
#include<algorithm>//sort()
#include<cmath>//sqrt()
#include<bitset>
#include<iomanip>//输出(小数点后)几位
using namespace std;
struct ty
{
    int dist,x,y;//len是线段距离,x与y分别是线段两端点(不是坐标,相当于点的索引)
}a[3000*2999/2+5];//C4000 2组合数,+5保险
int x[3005];int y[3005];//记录点的坐标
bitset<3005> b[3005];//定义了一个3005位bitset数组,数组b代表各个点,每个元素代表是否与其它点连接上
bool comp(struct ty a,struct ty b)
{
    return a.dist>b.dist;//按线段从长到短排序
}
int main()
{    
    ios::sync_with_stdio(false);cin.tie(nullptr);//加快输入输出
    int t=0;//后面先有个t++,故这里t令为0
    int n;
    cin>>n;输入点的个数
    for(int i=1;i<=n;i++)
    {
        cin>>x[i]>>y[i];//记录下每个点的坐标,方便以后算距离
    }
    for(int j=1;j<=n;j++)//枚举线段其中一个(左)端点的索引
    {
        for(int k=j+1;k<=n;k++)//枚举线段另外一个(右)端点的索引
        {    
             t++;
             a[t].dist=(x[j]-x[k])*(x[j]-x[k])+(y[j]-y[k])*(y[j]-y[k]);//两点间距离公式,不开根号。原因:1.不开根号减少复杂运算;2.开根号有精度丢失,有可能让两个距离本不一样的点“距离”一样了
             a[t].x=j;a[t].y=k;
        }
    }
    sort(a+1,a+t+1/*注意前面的t++在赋值操作之前,故t并没有被多加一次*/,comp);
    for(int i=1;i<=t;i++)//注意,从这里开始相当于开辟了一个全新的空的平面(bitset默认初始化为0),把线段从大到小一条一条往上加。之前a[t]中t从1开始,到当前的t结束,一共也是这么多条线段
    {
        if( ( b[a[i].x] & b[a[i].y] ) != 0 ){cout << fixed<< setprecision(8)/*输出小数点后八位,精度保险一点*/ <<(sqrt(a[i].dist))/2;break;}//与操作后不等于0,说明两者有共同交点(也可以用.any())。因为这是一片空的空间,刚开始没有点,两者有的公共点都是在它之间加上的,而加上的(线段)的端点都是先加长线段的,所以这条线就是三角形中的最短边
        else
        {
            b[a[i].x][a[i].y]=1;//否则加入这条线,即在bitset数组中记录这两条线的端点相互连接
            b[a[i].y][a[i].x]=1;
        }
    }
    
    return 0;
}