英语七选五乱蒙,当然是不重复地蒙。
求这个概率,最容易想到的当然是穷举法,但是七选五的穷举要求不重复,那么,使用递归来求解是一个不错的解决方案

本文主要使用python来实现

首先计算所有情况的总数

1
all=7*6*5*4*3

定义递归函数f(list),这个函数的作用就是选择一个答案并且保证这个答案与相应的正确答案不同,其中输入参数list代表之前的选择情况。

我们不妨记正确答案为[1,2,3,4,5]

如果列表长度已经达到了5,那么就说明选完了,将allIncorrect自增。

否则,挨个尝试选1~7,记作next,并且要使这个值不能是正确答案next!=len(list)+1,也不能重复出现next not in list,之后将list复制一份,添加next到末尾,继续调用f(list)

1
2
3
4
5
6
7
8
9
10
11
def f(list):
global allIncorrect
if len(list)==5:
allIncorrect+=1
return
for next in range(1,8):#1,2,3,4,5,6,7
if(next==len(list)+1 or next in list):
continue
list2=list[:]#copy
list2.append(next)
f(list2)

至于为什么列表要复制一份,是因为列表是一个python对象,平常使用“=”赋值,赋的是地址,也就是引用传递,也就是说这两个变量指向的是同一个列表

总代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
allIncorrect=0
all=7*6*5*4*3
def f(list):
global allIncorrect
if len(list)==5:
allIncorrect+=1
return
for next in range(1,8):
if(next==len(list)+1 or next in list):
continue
list2=list[:]
list2.append(next)
f(list2)
f([])#代表什么都没选
print(allIncorrect,"/",all," = ",allIncorrect/all)

这里也给一份CPP的实现(我CPP很烂,写得有点复杂了)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>

using namespace std;

const int END = -1;
//in this example,in order to calculate the length of an Array,we set the last item to -1 manully.
int len(int* array) {
int length = 0;
for (;array[length]!= END; length++) {}
return length+1;
}
//this func return the length without the last item
int len_effective(int* array) {
return len(array) - 1;
}
//create a new array which is one item longer than the previous ,append the num to the effective last
int* appendArray(int* array, int num) {
int length=len(array);
int* newArray = new int[length + 1];
for (int i = 0; i < length - 1; i++) {
newArray[i] = array[i];
}
newArray[length - 1] = num;
newArray[length] = END;
return newArray;
}
//to check whether an array contains a specific item
bool isContain(int* array, int item) {
int length = len_effective(array);
for (int i = 0; i < length; i++) {
if (array[i] == item) {
return true;
}
}
return false;
}
int all = 7 * 6 * 5 * 4 * 3;
int allIncorrect = 0;
void f(int* array) {
if (len_effective(array) == 5) {
allIncorrect++;
return;
}
for (int next = 1; next <= 7; next++) {
if (next == len_effective(array) + 1|| isContain(array, next)) {
continue;
}

f(appendArray(array,next));
}


}

int main()
{
f(new int[1] {END});
cout << "Prob: all_incorrect/all = " << allIncorrect << "/" << all << " = " << (float)allIncorrect / all<<endl;
system("pause");
return 114514;
}