前置知识:最小圆覆盖
洛谷P1742 最小圆覆盖
给定平面一定数量的点,找一个最小的圆,将所有点包含进去.
然后,就不记得是哪位大佬提出了一种$O(n)$的解决方式,随机增量法.
- 保证数据的随机性,我们使用$random\_shuffle$这个函数
- 我们要接受一个定理:如果点$p$不在集合$S$的最小覆盖圆内,那么肯定在$p\cup S$的最小覆盖圆上.
- 首先,假设我们已经求出了前$i$个点形成的最小覆盖圆
- 如果$i+1$这个点不在$C_i$圆内,那么该$P_{i+1}$必定在$C_{i+1}$上
- 那么我们以$P_{i+1}$为圆心,半径为$0$作为起始圆,找到第$j$个点,保证$dis\{i+1,j\}>$当前圆的半径.以这两点为圆$C_{i+1,j}$半径为$dis\{i+1,j\}$,圆心为$\frac{P_{i+1}+P_j}{2}$
- 再寻找第三个点不在$C_{i+1,j}$,设为第$k$个点,那么以$i,j,k$三点的圆即可被认为是期望的最小覆盖圆$C_{i+1,j,k}$
- 不断重复$3-6$步骤,即可得到答案.
体感就是$O(n^3)$的嘛,在数据不随机的情况下,会退化为$O(n^3)$,但在数据完全随机的情况下,预期期望复杂度为$O(n)$.
1 | cirles zuixiaoyuan_fugai(int l, int r) //最小圆覆盖 |
最小覆盖双圆问题
洛谷P4586 最小覆盖双圆问题
又是一道考验人类智慧的问题.
首先,我们考虑最好情况.及两圆半径相同,均分了两侧的点.
如下图:(大概的画画就行啦)
反正就是如何让两边的圆的半径接近相同.
很显然的二分,先对两边各做一次最小圆,得到两个圆的半径,我们只需要在大的半径里二分一哈.
然后就可以得到答案啦.
但是有个问题,划分两个集合的这条线可能是斜的,所以我们还要暴力转角.
每次转那么$1°$,转那么$180$次就差不多.
转的越多,精度越高,时间越长.(只要相信你自己是欧皇,你就可以不超时又$AC$)
1 |
|