CF333E Summer Earnings
题目
https://codeforces.com/problemset/problem/333/E
题解
知识点:枚举,图论,位运算。
题目要求从给定的坐标中的选取三个点为圆心,画出 个不相交且半径相等的圆,并求圆半径可能的最大值。
显然,题目可以转化为,任选三个点,找到构成三角形最短边长的 中的最大值,直接枚举三个点的复杂度是 是不行的。
考虑不从找点角度构成三角形,因为没有操作空间,而先预处理出边端点序号和边长信息记录到边结构体中,复杂度是 ,从找边角度去构成三角形。但单纯找边也是 ,需要优化。
既然要找到最长边,可以考虑先把边长从大到小排序,从长边到短边开始找,这样找到第一条能和已经遍历过的较长边构成三角的边就是最大的边。
每次处理一个边,将会记录边对应两个端点的互连的信息,表示这条边已枚举,这里可以给点结构体增设一个 变量 , 表示为这个点是否已与 号点相连,用 类型而不用 数组主要考虑到空间问题和位运算便捷的操作。
最后找到一条边,能和已经枚举的较长边互连成三角形,这条边边长的 即是答案。若要构成三角形,则这条边两个端点的有一个相同的连接点,而通过两个端点各自 进行 运算的结果可以得到两端点是否连接了同一个点。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; struct dot{ int x,y; bitset<3007> bs; }d[3007]; struct len_dot{ int len,a,b; }ld[3000*3000+7]; int cnt = 0; int dist2(int a,int b){ return (d[a].x - d[b].x)*(d[a].x - d[b].x) + (d[a].y - d[b].y)*(d[a].y - d[b].y); } bool cmp(len_dot a,len_dot b){ return a.len>b.len; } int main(){ int n; cin>>n; for(int i = 0;i<n;i++){ cin>>d[i].x>>d[i].y; } for(int i = 0;i<n;i++){ for(int j = i+1;j<n;j++){ ld[cnt].len = dist2(i,j); ld[cnt].a = i; ld[cnt].b = j; cnt++; } } sort(ld,ld+cnt,cmp); double ans; for(int i = 0;i<cnt;i++){ if((d[ld[i].a].bs & d[ld[i].b].bs).any()){ ans = sqrt(ld[i].len)/2; break; } d[ld[i].a].bs[ld[i].b] = 1; d[ld[i].b].bs[ld[i].a] = 1; } cout<<fixed<<ans<<'\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16379367.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧