【杂谈】英语7选5引发的思考
本篇文章,我们不聊密码学蛤,因为我突然看到了一个应用的新题型,发现挺有意思的,这年头,高考英语都有新题型了,我当时是没做过,别害怕,本篇文章呢我们不来讲英语蛤,看到这个题目时候,我突然想到一个问题,就是这个题目,如果完全靠猜,得分的数学期望是多少,以及具体的分布列。这里,读者可以先想一想,这个期望具体是多少(为了后续好计算,我们后面按照一题一分来处理)?
初次尝试
这里,作为一个开发,手算肯定是不可能的,直接写一个代码来列举一下所有的情况了,这里,代码思路也比较好处理,我们假设一个正确答案,然后枚举所有可能情况,然后看一下和正确答案差异的数量就可以了,这里代码写的通用一些,为了后续做准备,这里,考虑用Rust来实现吧。
use colored::*;use std::collections::HashMap;#[derive(Debug, Clone)]structPermutation { choices: Vec<usize>,}impl Permutation {fnnew(choices: Vec<usize>) -> Self {Self { choices } }fnmatches(&self, correct: &[usize]) -> usize {self.choices .iter() .zip(correct.iter()) .filter(|(a, b)| a == b) .count() }}structPermutationGenerator { n: usize, k: usize,}impl PermutationGenerator {fnnew(n: usize, k: usize) -> Self {Self { n, k } }fngenerate(&self) -> Vec<Permutation> {letmut result = Vec::new();letmut current = Vec::new();letmut used = vec![false; self.n];self.generate_recursive(&mut result, &mut current, &mut used); result }fngenerate_recursive( &self, result: &mutVec<Permutation>, current: &mutVec<usize>, used: &mut [bool], ) {if current.len() == self.k { result.push(Permutation::new(current.clone()));return; }for i in0..self.n {if !used[i] { used[i] = true; current.push(i + 1);self.generate_recursive(result, current, used); current.pop(); used[i] = false; } } }}structStatistics { match_counts: HashMap<usize, usize>, total: usize, n: usize, m: usize,}impl Statistics {fnnew(n: usize, m: usize) -> Self {Self { match_counts: HashMap::new(), total: 0, n, m, } }fnadd(&mutself, matches: usize) { *self.match_counts.entry(matches).or_insert(0) += 1;self.total += 1; }fndisplay(&self, correct_answer: &[usize]) {self.print_correct_answer(correct_answer);self.print_separator();self.print_statistics();self.print_separator();self.print_total(); }fnprint_correct_answer(&self, correct: &[usize]) {println!("n{} {:?}", "正确答案:".bright_green().bold(), correct); }fnprint_separator(&self) {println!("{}", "─".repeat(60).bright_black()); }fnprint_statistics(&self) {println!("n{}", "匹配统计:".bright_yellow().bold());println!();for i in0..=self.m {let count = self.match_counts.get(&i).unwrap_or(&0);let percentage = (*count asf64 / self.total asf64) * 100.0;let bar_length = (percentage / 2.0) asusize;let bar = "█".repeat(bar_length);let label = format!("{} 个正确", i);let ratio = i asf64 / self.m asf64;let color_label = match ratio { r if r < 0.2 => label.red(), r if r < 0.4 => label.bright_red(), r if r < 0.6 => label.yellow(), r if r < 0.8 => label.bright_yellow(), r if r < 1.0 => label.bright_green(), _ => label.green().bold(), };println!(" {} │ {:>6} 种 │ {:>6.2}% │ {}", color_label, count.to_string().bright_white().bold(), percentage, bar.bright_blue() ); } }fnprint_total(&self) {println!();println!("{} {}","总排列数:".bright_cyan().bold(),self.total.to_string().bright_white().bold() );println!();let expected = self.calculate_expected_total();println!("{} P({}, {}) = {}","理论值:".bright_cyan(),self.n,self.m, expected.to_string().bright_white() );println!(); }fncalculate_expected_total(&self) -> usize { (self.n - self.m + 1..=self.n).product() }}fnmain() {let (n, m) = (7, 5);let correct_answer: Vec<usize> = (1..=m).collect();let generator = PermutationGenerator::new(n, m);let permutations = generator.generate();letmut stats = Statistics::new(n, m);for perm in &permutations {let matches = perm.matches(&correct_answer); stats.add(matches); } stats.display(&correct_answer);}可以看到,具体的结果如下。
我们可以计算一下具体的期望,最终结果如下,
结果非常的Amazing啊,居然蒙对的期望不到1,这样这个问题其实就解决了,但是发现一个非常有趣的现象,就是,如果我只选择一个选项,比如全选A,那么我得分的期望也是。这个就非常好计算了,因为7个里面一定有5个是正确的,但是这个现象是巧合吗?如果从个里面随机选择个,那么正确的个数的数学期望以及分布列是多少呢?
进一步探讨,简化模型
我们先考虑一种特殊的情况,也就是的时候,这应该是比较好讨论的部分,这里我们先来观察。
只有一个选项的情况
这一种情况,就相当的好处理了,因为,就一个,那么这里的数学期望是1,这没啥好说的。
有2个选项的情况
这一种情况,也非常简单,要么全对,要么全错。
这里,的期望也比较好计算,可以看到具体是
有3个选项的情况
这里,同样的方式,我们来看一下具体的数学期望
结果非常的Amazing啊,这里期望都是1,同样的,我们可以看一下有4个选项的情况
有4个选项的情况
可以计算得到,他的期望也是1,这里不相信的读者,可以自行计算一下,这里不列式子了。
猜想的推导
这里,我们是不是可以猜测对于所有的,这里的数学期望都是1呢?或者我们换一种角度来思考一下,这里对于每一个位置i,他被分配到正确的位置的概率都是,从这个角度来看,这里的期望确实是1,没毛病,也就是
接下来,我们来推导一下,分布列,这里需要用到一点点排列组合的知识,也就是错排公式[2],
我们知道了错排问题的公式,来计算分布列就简单多了,我们可以把选择分成2个步骤,也就是乘法原理。
首先选择k个正确位置的排列,这里具体的排列数量为
那么剩余的就是全部排错的数量,具体的数量为
总的排列数量是,因此我们可以得到概率公式,
这里k是正确题目的数量。通过上述的讨论,我们非常惊奇的可以得到一个组合恒等式,
哎,对,没用的知识增加了。好了,有了这个一个推导的结论,我们可以来看一下,最原始的题目了,也就是n个里面选m个情况。
真实情况
这里,对于期望,实际上也是非常好计算的,也就是正确的选项的概率是,所以期望是。我们来看一下每一种情况的概率吧,多水一点字数。这里,我们需要用到另外一个组合学的知识,那就是容斥原理[3],这里公式自己看参考资料吧,不粘贴出来了。
我们还是沿用之前的推导思路,这里恰好有k个空位正确,也就是固定k个空位正确,那么其余个空位全部错误,这里对于正确空位的选择有
个方式。
接下来,我们需要考虑剩余的个空位,这里不能直接用错排了,我们需要用容斥原理来思考,就是假设有s个空位是正确的,那么我们只需要用全排列减去正确的就可以了,也就是
然后,我们综合一下,就可以得到对应的概率
然后观察一下,如果,恭喜你,成功推导出了经典的错排公式,也就是
好了,没用的知识,再次的增加了呢。
总结
这里,我们通过一个有趣的英语题出发,得到了一个非常有趣的现象,那就是,你如果纯靠猜,实际上你的正确的个数是不到一个的,除非你是天命之人,哈哈,而且这个对于n选n来说,这个的期望值固定是1个,这也就是说,而且你还有很大的概率是一个不对的,如果求稳的话,可以直接全选一样的,大数定律对于个体无效哦,当然,玩归玩,闹归闹,如果有高中生看到这篇文章,你们就放弃猜七选五吧,与其寄希望于运气,不如依靠实实在在的技巧,认真学习,认真备考,好了,快乐的时光过得特别快,又到了说再见的时候了,咱们下次再见~
参考资料
https://gaokao.eol.cn/shiti/yy/202506/t20250612_2674288_4.shtml https://zh.wikipedia.org/wiki/%E9%94%99%E6%8E%92%E9%97%AE%E9%A2%98 https://zh.wikipedia.org/wiki/%E6%8E%92%E5%AE%B9%E5%8E%9F%E7%90%86
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……




还没有评论,来说两句吧...