求解树下人群最小阴影周长及代码TLE优化方案
最小阴影周长问题的超时优化方案
核心解法回顾
要覆盖所有人群的最小圆形阴影,半径等于所有点到原点(0,0)的距离最大值,周长计算公式为 2 * π * r。你的思路完全正确:先计算每个点的距离平方(规避提前开根号的开销),取最大值后再开根号得到半径r。
超时问题的针对性优化
1. 聚焦sqrt的高效计算
你怀疑sqrt导致超时是合理的,但核心优化点不是去掉sqrt(毕竟最终必须计算半径),而是确保使用语言内置的优化sqrt函数:
- 比如C++用
std::sqrt或sqrtl,Python用math.sqrt,这些都是经过底层优化的实现,远快于手动编写的牛顿迭代等方法。
2. 消除遍历过程的冗余开销
如果测试用例数据量极大(比如单例包含1e6+个点),遍历阶段的细节会直接影响性能:
- 计算距离平方时,用
x*x + y*y代替pow(x,2)+pow(y,2)——pow函数的调用开销远高于直接乘法。 - 用64位整数(如C++的
long long、Python的int)存储距离平方,避免整数溢出,同时减少类型转换的额外消耗。 - 遍历过程中实时更新最大距离平方,无需存储所有点的距离平方值,节省内存的同时提升缓存命中率。
3. 输入输出加速(关键优化点)
很多大数据量测试用例的超时根源不是计算,而是输入输出速度慢:
- C++环境下,添加
ios::sync_with_stdio(false); cin.tie(nullptr);关闭IO同步,能大幅提升输入效率。 - Python环境下,用
sys.stdin.read()批量读取输入再拆分,替代逐行读取的方式,进一步加速。
示例优化代码(C++)
#include <iostream> #include <cmath> using namespace std; const double PI = acos(-1.0); int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; while (T--) { int n; cin >> n; long long max_dist_sq = 0; for (int i = 0; i < n; ++i) { long long x, y; cin >> x >> y; long long dist_sq = x * x + y * y; if (dist_sq > max_dist_sq) max_dist_sq = dist_sq; } double perimeter = 2 * PI * sqrt(max_dist_sq); cout.precision(12); cout << perimeter << '\n'; } return 0; }
示例优化代码(Python)
import math import sys PI = math.acos(-1.0) def main(): input_data = sys.stdin.read().split() ptr = 0 T = int(input_data[ptr]) ptr += 1 for _ in range(T): n = int(input_data[ptr]) ptr += 1 max_dist_sq = 0 for __ in range(n): x = int(input_data[ptr]) y = int(input_data[ptr+1]) ptr += 2 dist_sq = x*x + y*y if dist_sq > max_dist_sq: max_dist_sq = dist_sq perimeter = 2 * PI * math.sqrt(max_dist_sq) print(perimeter) if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者NAFIZ MUNTASIR
相关产品推荐
相关产品推荐

