文章目录

  • 题目描述
    • 数据范围
  • 解析
  • 代码

图片转载自: https://blog.csdn.net/weixin_43346722/article/details/118435430

题目描述

平面上有 n个点,用n个大小相同的圆分别将一个点作为圆心,同时满足圆圈不相交,求圆的最大半径。

数据范围

2<=n<=2e52<=n<=2e52<=n<=2e5

解析

把题目抽象一下就是求最小的一对点的距离除以2
考虑如何求呢?
暴力当然是会T飞的
首先把所有点按x排序
然后考虑分治
分治的关键是如何把两个小问题合并
暴力合并还是n方…
我们考虑剪掉一些不必要的比较
设两边分别得到的答案的最小值为a
那么x距离大于a的肯定不用比了
但是一旦x的距离全在a里面咋办?
同理,我们按y再排一下序,y的距离大于a都不用算了
那么每个点对应的的计算范围大概就是这样:


那么这样就不会有很多点了吗?
我们还有一个了一个关键性质:左边和右边的点各自之间的距离都不小于a
那么右边这个矩形里能填的两两距离不小于a的点就不多了
关于这个,我们就要使用神奇的鸽巢原理
考虑矩形按照下面这个图分区:

每个小矩形的对角线长度小于a,所以每个矩形最多有一个点
所以大矩形内的点不超过6个
(同时我们把6个点放到四角和两长边的终点,其实也就可以构造出6个的方案)
所以我们每个点需要计算的点最多不超过6个
时间复杂度降为线性,问题得以解决
整体复杂度:nlognnlognnlogn(每次合并按ysort可能再大一些?)

代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+100;
const int M=2e6+100;
#define ll long long
ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();};while(isdigit(c)){x=x*10+c-'0';c=getchar();};return x*f;
}
int n,m;
struct node{double x,y;
}p[N],tmp[N],now[N];
bool cmpx(node a,node b){return a.x<b.x;}
bool cmpy(node a,node b){return a.y<b.y;}
double dis(node a,node b){//printf("  dis:");print(a);print(b);printf("%lf+%lf=%lf")return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void print(node o){printf("(%.2lf %.2lf)",o.x,o.y);}
double solve(int l,int r){if(l==r) return 2e9;int mid=(l+r)>>1;double res=min(solve(l,mid),solve(mid+1,r));int num=0,tot=0;for(int i=mid+1;i<=r;i++){if(p[i].x-p[mid].x>=res) break;tmp[++num]=p[i];//printf("tmp:");print(p[i]);putchar('\n');}for(int i=mid;i>=l;i--){if(p[mid+1].x-p[i].x>=res) break;now[++tot]=p[i];//printf("now:");print(p[i]);putchar('\n');}sort(tmp+1,tmp+1+num,cmpy);sort(now+1,now+1+tot,cmpy);int pre=1;for(int i=1;i<=tot&&pre<=num;i++){while(pre<=num&&now[i].y-tmp[pre].y>=res) pre++;for(int j=pre;tmp[j].y-now[i].y<res&&j<=num;j++){//printf("i=%d j=%d dis=%.2lf",i,j,dis(now[i],tmp[j]));print(now[i]);print(tmp[j]);putchar('\n');res=min(res,dis(now[i],tmp[j]));}}return res;
}
int main(){while(1){n=read();if(n==0) return 0;for(int i=1;i<=n;i++){scanf("%lf%lf",&p[i].x,&p[i].y);}sort(p+1,p+1+n,cmpx);printf("%.2lf\n",solve(1,n)/2);}return 0;
}
/*
2
0 0
1 1
2
1 1
1 1
3
-1.5 0
0 0
0 1.5
0
*/

YBTOJ:圈套问题(分治法、鸽笼原理)相关推荐

  1. 算法中的递归分析和分治法的原理

    分析递归算法三种方法 替换法.迭代法.通用法(master method) 作用:分析递归算法的运行时间 分治算法 将一个问题分解为与原问题相似但规模更小的若干子问题,递归地解这些子问题,然后将这些子 ...

  2. 分治法的经典问题——大整数相乘

    分治法的经典问题--大整数相乘 分治法的原理 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同.求出子问题的解,就可得到原问题的解.即一种分目标 ...

  3. [转载] 算法导论:分治法,python实现合并排序MERGE-SORT

    参考链接: Python中的合并排序merge sort 1. 简单合并排序法实现 思想:两堆已排好的牌,牌面朝下,首先掀开最上面的两张,比较大小取出较小的牌,然后再掀开取出较小牌的那一堆最上面的牌和 ...

  4. 代码分析+原理图解——棋盘覆盖问题-分治法

    上算法课时,老师以文字+代码的方式讲了这道题,然而有很多同学反映听的不是太懂, 我们接触事物最直观的就是以图片理解,因此我尝试使用图解法来帮助大家理解. 问题描述:   注意:分治法最核心的一点是:分 ...

  5. 算法设计与分析 实验二 分治法求解最近点对问题

    分治法求解最近点对问题 一.实验目的与要求 1.实验基本要求 2.实验亮点 二.实验内容与方法 三.实验步骤与过程 (一)一些准备工作 1.实验流程 2.数据生成与去除重复点 (二)暴力穷举法 1.算 ...

  6. 算法导论-排序算法-分治法

    1.分治法原理 所谓的分治指的就是分而治之,即将大规模的问题分解成几个较小规模的问题.通过对较小规模问题的求解达到对整个问题的的求解.当我们将问题分解成两个较小问题求解时的分治方法就是二分法. 分支的 ...

  7. java分治法求数列的最大子段和_同事为进大厂天天刷Java面试题,面试却履败!究其原因竟是它在捣鬼。...

    写在前面 疫情过后,招聘与求职受影响到底有多大?我不知道,但我的真实感受是,即使有疫情的影响,最近还是持续有朋友来跟我说他们今年工作的新动向.有人跳槽去了大厂,有人下定决心出来创业,也有人还在观望,等 ...

  8. 棋盘覆盖-分治法(代码实现)

    这是棋盘覆盖的代码实现,至于原理,请参考我的上一篇博客:棋盘覆盖问题-分治法 实现的效果如下: 或者如下: 其中0表示递归过程中标记的所有奇异点 实现代码如下: //棋盘大小size, 奇异点的坐标( ...

  9. 最近点对问题(分治法)

    问题描述 给定平面S上n个点,找其中的一对点,使得在n个点组成的所有点对中,该点对间的距离最小 蛮力法求解 点的存储: class Point{//横坐标int x;//纵坐标int y;/*** 求 ...

  10. 实验一 分治与递归—用分治法实现元素选择 java算法

     提高题二:用分治法实现元素选择 一.实验要求与目的 1.了解分治法的基本思想,掌握递归程序编写方法: 2.使用分治法编程,求解线形序列中第k小元素. 二.实验内容 1.  给定线形序列集中n个元素和 ...

最新文章

  1. JS子窗口调用父窗口中的函数
  2. 消息队列系列(三):.Rabbitmq Trace的使用
  3. Python学习之字符串格式化
  4. nginx + openssl 搭建需要身份验证的文件下载服务器
  5. Linux find查找文件夹(目录)所在位置
  6. FLASH ERASE:CHIP、BLOCK、SECTOR
  7. 如何正确选择合适的贷款机构,避免征信花掉?
  8. 编译安装mysql5.6.36_MySQL5.6.36编译安装
  9. 自动化比手工测试成本高?使用Selenium评估测试自动化的ROI指标
  10. mrc20温控f1什么意思_精确率、召回率、F1 值、ROC、AUC 各自的优缺点是什么?
  11. UVa 10491 - Cows and Cars(全概率)
  12. asp.net MVC使用 jsQR 扫描二维码
  13. html 游戏 消消乐,html5叠房子消消乐小游戏代码
  14. 企业会计准则第34号——每股收益(2006)
  15. 连续词袋模型(Continous bag of words, CBOW)
  16. 人脸识别开源库face_recognition
  17. 易得无价宝,难得有情郎
  18. zeek系列之:流量数据采集流量探针zeek-脚本入门
  19. 涠洲岛日出日落时间表,1月10日涠洲岛开船时间/日出日落/天气预报
  20. 最新最全的免费股票数据接口--沪深A股实时融资融券数据API接口(六)

热门文章

  1. 中科大计算机博士毕业条件,中国科技大学博士和硕士研究生毕业要求.doc
  2. 道德经和译文_老子《道德经》第九章原文、注释、译文、导读及解析(收藏版)...
  3. java 进程同步代码_java 实现进程间的同步(源代码)
  4. .gpg 进程 linux,小知识之Linux系统中的最大进程数,最大文件描述,最大线程数...
  5. 怎么从转移特性曲线上看dibl_「科普向」这篇让你快速搞懂IGBT的静态特性
  6. 2023届春招实习拉钩一面凉经
  7. 7-6 0-1背包 (20 分)(思路加详解+网格做法+动态规划)Come Baby !!!!!!!!!!!!!!
  8. [MyBatisPlus]通用枚举
  9. [Redis6]新数据类型_Geospatial
  10. 数据结构与索引-- B+树索引