这道题目是一道不错的计算几何题,题意是在一个平面上,有若干个圆(题目中称为商场)。然后需要以这些圆中的某一个圆的圆心为圆心画一个圆(题目中称为),使得新画的这个圆能够覆盖任何一个其它的圆的至少一半的面积。求这个圆的最小半径。

这道题的思路是,枚举每一个圆的圆心,然后以它为圆心画圆。用二分法处理半径,每枚举一个半径就尝试看能不能满足覆盖条件。然后找到最短的半径就行了。

这道题有至多 10 个 cases, 至多 20 个圆。圆心的坐标范围是 [-10000, 10000], 半径范围是 [1, 2000], 输入数据都是整数。输出要求精确到 1e-4 这样。

这题我尝试了很多次才 AC. 需要注意的问题是:

  • 计算几何中如果用浮点一定要看准条件,尽量用 double. 如果数据到了 1e4 这种数量级,那么小数点要是表示到 4 位还是很有压力了。
  • 这个坐标范围是 -10000 到 10000, 加上半径可以到 2000 这个条件,整个平面中可能产生的长度就可能达到 [latex]4000 + 10000 \sqrt{2}[/latex] 之多。一开始我以为令 [latex]\infty = 11111.0[/latex] 都已经便宜它了,后来 WA 才知道,唉。
  • 还有那个 eps 也是要设得小一点,设置成 1e-5 都可能四舍五入错误的。其实设小一点时间完全够的。
  • 我本来居然以为两圆如果是包含关系可以直接 pass, 后来 WA 了几次才发现其实如果是商场把伞给包了就跪了。

还有就是有的时候计算几何也确实容易莫名其妙地跪,比如以前似乎 POJ 如果输出 double%lf 就不行(现在不知道可以了没有),用 %f 才可以。

在训练计算几何题目的时候使用数据生成器确实不错,从网上搜索标程,然后生成大量的数据,分别用标程和自己的程序来跑一跑,用专门的比较软件(比如 KDiff)比较一下,确实能够发现问题。

本题源代码

数据生成器源代码

原创文章,转载请注明来源:http://euyuil.com/3129/acm-icpc-2009-ningbo-open-air-shopping-malls/