题目链接

小红的碾压墙

题目描述

场上初始有 个敌方随从。小红使用两张“致命射击”,每张会随机消灭一个敌方随从,且两张牌不会消灭同一个随从。如果这两张牌恰好消灭了最左边和最右边的随从(即造成了“碾压墙”的效果),求这个事件发生的概率。

解题思路

这是一个经典的古典概率问题。概率的计算公式为:

  1. 计算所有可能发生的事件总数

    • 第一张“致命射击”有 个目标可以选择。
    • 由于两张牌不会消灭同一个随从,当第一张牌消灭一个随从后,场上还剩下 个随从。
    • 因此,第二张“致命射击”有 个目标可以选择。
    • 考虑到射击的先后顺序,所有可能发生的、有序的击杀组合总数为
  2. 计算满足条件的事件数

    • “碾压墙”效果要求消灭最左边和最右边的随从。
    • 满足条件的事件只有两种有序的组合:
      • 第一张击杀最左边的随从,第二张击杀最右边的随从。
      • 第一张击杀最右边的随从,第二张击杀最左边的随从。
    • 所以,满足条件的事件数恰好为 2。
  3. 计算概率

    • 将上述结果代入概率公式,可得所求概率为: [ P = \frac{2}{n \cdot (n-1)} ]
    • 时,场上只有两个随从(最左和最右),任何两张致命射击必然会消灭它们,概率为 ,符合直觉。

实现时,只需读取 ,然后根据公式计算即可。注意要使用浮点数进行除法运算,并按要求格式化输出。

代码

#include <iostream>
#include <iomanip>

// C++ Solution
void solve() {
    int n;
    std::cin >> n;
    if (n < 2) {
        // 题目保证 n >= 2,但作为防御性编程
        std::cout << std::fixed << std::setprecision(10) << 0.0 << std::endl;
        return;
    }
    double probability = 2.0 / (static_cast<double>(n) * (n - 1));
    std::cout << std::fixed << std::setprecision(10) << probability << std::endl;
}

int main() {
    solve();
    return 0;
}
import java.util.Scanner;

// Java Solution
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        if (n < 2) {
            System.out.printf("%.10f\n", 0.0);
            return;
        }
        double probability = 2.0 / ((double)n * (n - 1));
        System.out.printf("%.10f\n", probability);
    }
}
# Python Solution
def solve():
    try:
        n = int(input())
        if n < 2:
            print(f"{0.0:.10f}")
            return
        
        probability = 2.0 / (n * (n - 1))
        print(f"{probability:.10f}")
    except (ValueError, EOFError):
        pass

if __name__ == "__main__":
    solve()

算法及复杂度

  • 算法:数学/概率计算

  • 时间复杂度

    • 代码只涉及一次读取和几次基本的算术运算。
  • 空间复杂度

    • 只需要常数级别的额外空间来存储输入的变量。