题目翻译与分析
题目背景
阿兹特克国王非常富有,他订购了一批半径相同的玻璃圆(在二维问题中视为圆形)作为宫殿装饰品。由于玻璃易碎,运输时需要将它们装在正方形的盒子里,并且要确保圆在盒子内不能移动(即刚性堆积)。国王的要求很特别:盒子要尽可能大(而不是尽可能小),同时必须保持正方形。每个盒子可以装 999 个或 101010 个圆。
输入输出
- 输入:多个测试用例,每个用例一行,包含一个实数 rrr (0<r<1070 < r < 10^70<r<107),表示圆的半径。输入以 EOF\texttt{EOF}EOF 结束。
- 输出:对于每个测试用例,输出两个值,保留 555 位小数:
- 装 999 个圆的盒子边长
- 装 101010 个圆的盒子边长
两个值之间用一个空格隔开。
样例
样例输入
0.00001
0.00002
0.00003
样例输出
0.00007 0.00008
0.00014 0.00015
0.00021 0.00023
解题思路
1. 问题本质
本题是一个几何最优化问题。我们需要找到正方形盒子的最大边长,使得给定数量的等大圆在盒内无法移动(即刚性堆积)。这里的“无法移动”意味着圆与圆、圆与盒壁之间是紧密接触的,且整个结构在几何上是稳定的。
2. 直观尝试与复杂性
- 999 个圆:最自然的想法是排成 3×33 \times 33×3 的网格,此时盒子边长为 6r6r6r。但样例输出显示 r=0.00001r=0.00001r=0.00001 时边长约为 0.000070.000070.00007,即 7r7r7r,说明 6r6r6r 并非最优。因此,更优的排列方式可能不是简单的网格,而是允许圆与盒壁之间留有空间,但整体结构仍然刚性。
- 101010 个圆:排列方式更加复杂,常见的尝试有“金字塔形”(4−3−34-3-34−3−3)或“菱形”(4−4−24-4-24−4−2),但样例输出的比例也并非简单的 8r8r8r 或 7r7r7r。
3. 已知的最优解常数
本题的最优解是通过精确的几何计算或数值优化得到的一组固定比例常数。对于给定的半径 rrr,最优边长可以表示为:
L9=k9⋅r
L_9 = k_9 \cdot r
L9=k9⋅r
L10=k10⋅r
L_{10} = k_{10} \cdot r
L10=k10⋅r
其中:
k9≈7.0225095034303809
k_9 \approx 7.0225095034303809
k9≈7.0225095034303809
k10≈7.5191308906315991
k_{10} \approx 7.5191308906315991
k10≈7.5191308906315991
这两个常数是通过求解非线性方程组(包括圆与圆、圆与盒壁的接触条件,以及整体结构的几何约束)得到的。由于计算过程复杂,且题目允许使用特判,我们直接使用这些已知常数即可。
4. 为何这样可行
- 刚性条件 意味着所有接触点都是切点,且系统没有自由度。
- 最大化边长 意味着我们需要在保持刚性的前提下,让圆与盒壁之间留有尽可能大的间隙。
- 对于 999 个圆,最优排列可能是一个倾斜的网格或部分偏移的结构。
- 对于 101010 个圆,最优排列可能是一个中心对称的堆积,允许盒壁与最外层圆之间保持一定距离。
- 由于比例是固定的,我们只需将 rrr 乘以对应常数即可得到答案。
参考代码
// Rigid Circle Packing
// UVa ID: 10468
// Verdict: Accepted
// Submission Date: 2025-12-05
// UVa Run Time: 0.030s
//
// 版权所有(C)2025,邱秋。metaphysis # yeah dot net
#include <bits/stdc++.h>
using namespace std;
int main() {
// 最优比例常数,来自几何推导
const double ratio9 = 7.0225095034303809;
const double ratio10 = 7.5191308906315991;
double radius;
while (cin >> radius) {
double side9 = radius * ratio9;
double side10 = radius * ratio10;
cout << fixed << setprecision(5) << side9 << " " << side10 << endl;
}
return 0;
}
UVa 10468 刚性圆堆积解析
694

被折叠的 条评论
为什么被折叠?



