#include #include #include #include #include // 使用 C++11 的随机数生成工具,比 rand() 质量更高 std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count()); /** * @brief 生成一个在 [min, max] 范围内的均匀分布的浮点数 * @param min 范围下界 * @param max 范围上界 * @return 随机浮点数 */ double random_double(double min, double max) { std::uniform_real_distribution dist(min, max); return dist(rng); } int main() { // 设置 IO 加速,在 OI/ACM 竞赛中常用 std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); // --- 问题参数 --- const double L = 3.0; // 木棍总长度 const int NUM_TRIALS = 10000000; // 模拟试验次数,次数越多结果越接近理论值 int success_count = 0; // 能够构成三角形的成功次数 // --- 蒙特卡洛模拟 --- for (int i = 0; i < NUM_TRIALS; ++i) { // 1. 在木棍上随机选择两个断点 double break1 = random_double(0.0, L); double break2 = random_double(0.0, L); // 2. 确定两个断点的位置,方便计算三段长度 double p1 = std::min(break1, break2); double p2 = std::max(break1, break2); // 3. 计算三段的长度 double seg1 = p1; double seg2 = p2 - p1; double seg3 = L - p2; // 4. 检查是否能构成三角形 // 充要条件:任意一边的长度都小于总长度的一半 double half_L = L / 2.0; if (seg1 < half_L && seg2 < half_L && seg3 < half_L) { success_count++; } } // --- 输出结果 --- double probability = static_cast(success_count) / NUM_TRIALS; std::cout << "--- 蒙特卡洛模拟解决木棍折断问题 ---" << std::endl; std::cout << "木棍长度 (L): " << L << std::endl; std::cout << "模拟次数 (N): " << NUM_TRIALS << std::endl; std::cout << "成功次数: " << success_count << std::endl; std::cout << std::fixed << std::setprecision(6); std::cout << "模拟得到的概率 P ≈ " << probability << std::endl; std::cout << "理论概率 P = 0.25" << std::endl; return 0; }