题目链接
题目描述
场上初始有 个敌方随从。小红使用两张“致命射击”,每张会随机消灭一个敌方随从,且两张牌不会消灭同一个随从。如果这两张牌恰好消灭了最左边和最右边的随从(即造成了“碾压墙”的效果),求这个事件发生的概率。
解题思路
这是一个经典的古典概率问题。概率的计算公式为:。
-
计算所有可能发生的事件总数
- 第一张“致命射击”有
个目标可以选择。
- 由于两张牌不会消灭同一个随从,当第一张牌消灭一个随从后,场上还剩下
个随从。
- 因此,第二张“致命射击”有
个目标可以选择。
- 考虑到射击的先后顺序,所有可能发生的、有序的击杀组合总数为
。
- 第一张“致命射击”有
-
计算满足条件的事件数
- “碾压墙”效果要求消灭最左边和最右边的随从。
- 满足条件的事件只有两种有序的组合:
- 第一张击杀最左边的随从,第二张击杀最右边的随从。
- 第一张击杀最右边的随从,第二张击杀最左边的随从。
- 所以,满足条件的事件数恰好为 2。
-
计算概率
- 将上述结果代入概率公式,可得所求概率为: [ 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()
算法及复杂度
-
算法:数学/概率计算
-
时间复杂度:
。
- 代码只涉及一次读取和几次基本的算术运算。
-
空间复杂度:
。
- 只需要常数级别的额外空间来存储输入的变量。