day2
给$n$个点,从中选$4$个点组成四边形,求最小四边形面积,$n \lt 2000$。
给$n$个点,从中选$4$个点组成四边形,求最大四边形面积,$n \lt 2000$。
最小四边形
思路
先考虑三角形。要使得三角形面积最小,这个面积的贡献点一定是以其中一个点为中心,旋转一个很小的弧度得到的。
拓展到四边形,可以猜测依旧有如上性质。
所以不妨枚举所有点$a$,以$a$为原点进行极角排序,那么得到的$p[]$一定都是有序排列的,且相邻的$b,c,d$和$a$组成的四边形一定是最小面积的可行解。
由于这个四边形可以是凹的,所以分类讨论:
- $S_{abc} + S_{acd} > S_{abd} $,说明四边形是凸的;
- 否则直接得出 $min( S_{abc}+min(S_{acd},S_{bcd}),S_{acd}+S_{bcd} )$,求出最小的凹四边形。
tips
注意极角排序时,尽量避免使用$atan2$函数,改用叉积排序,因为$atan2$的效率非常低。
代码
1 | const int maxn = 6005; |
最大四边形
思路
首先可以从三角形推断,最大三角形落在凸包上,那么最大四边形肯定也落在凸包上。
然后构建出凸包,用旋转卡壳求出以点$a,b$为对角线得到的最大四边形便可,注意另外两点$c,d$一定是分布在$a,b$的两侧,且这个四边形一定是凸包。
如果不存在这样的四边形,说明凸包大小为3,那么只需要在剩余点里找一个点,然后构建凹四边形,再算答案便可。
tips
凸包板子一定要检查一遍!!!
两个子问题合二为一的代码
1 |
|
- 5/19 upd:发现存在误差,已修改,不确定正确性。
- 直接上标程:
1 |
|