题目
我这次很难得把题目放上来,是因为我真的想吐槽一下自己的语文。
题意理解
我的思路和官方题解思路是一致的,但是由于是用的Java写的,我不知道怎么枚举,就用了dfs,实际效果是一样的。
官方题解
算出一个题被做出来的概率,然后 212 枚举一下每个题是否被做出来,算算贡献
我的理解
首先这题,是说你做出来总共0题-12题的概率,这点我一开始没有反应过来。后面被坑到的人更多。
其次,对于题目
i
,你解不出来的概率应该是
等公式推出来了,其实就很好写了。
代码
import java.math.BigDecimal;
import java.util.Scanner;
public class Main {
static BigDecimal[] a = new BigDecimal[13];
static BigDecimal[] b = new BigDecimal[13];
static BigDecimal[] c = new BigDecimal[13];
static BigDecimal[] pro = new BigDecimal[13];
static boolean[] passed = new boolean[13];
static void dfs(int n) {
if (n == 13) {
BigDecimal temp = new BigDecimal(1);
int cnt = 0;
for (int i = 1; i < 13; i++) {
if (passed[i]) {
cnt++;
temp = temp.multiply(a[i]);
} else {
temp = temp.multiply(BigDecimal.ONE.subtract(a[i]));
}
}
pro[cnt] = pro[cnt].add(temp);
return;
}
passed[n] = true;
dfs(n + 1);
passed[n] = false;
dfs(n + 1);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
a[0] = BigDecimal.ZERO;
for (int i = 1; i < 13; i++) {
a[i] = scanner.nextBigDecimal();
}
b[0] = BigDecimal.ZERO;
for (int i = 1; i < 13; i++) {
b[i] = scanner.nextBigDecimal();
}
c[0] = BigDecimal.ZERO;
for (int i = 1; i < 13; i++) {
c[i] = scanner.nextBigDecimal();
}
scanner.close();
for (int i = 0; i < 13; i++) {
a[i] = a[i].add(BigDecimal.ONE.subtract(a[i]).multiply(b[i]));
a[i] = a[i].add(BigDecimal.ONE.subtract(a[i]).multiply(c[i]));
}
for (int i = 0; i < 13; i++) {
pro[i] = BigDecimal.ZERO;
}
dfs(1);
for (int i = 0; i < 13; i++) {
System.out.printf("%f\n", pro[i]);
}
}
}
补充内容
关于暴力枚举的部分,应该是我昨晚失了智。其实用Java和用cpp在枚举上相差不大。还是写一下吧。
#include <cstring>
#include <iostream>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
double a[13];
double b[13];
double c[13];
double pro[13];
double pass[13];
int main() {
for(int i = 0; i < 12; i++) {
scanf("%lf", &a[i]);
}
for(int i = 0; i < 12; i++) {
scanf("%lf", &b[i]);
}
for(int i = 0; i < 12; i++) {
scanf("%lf", &c[i]);
pass[i] = 1 - (1 - a[i]) * (1 - b[i]) * (1 - c[i]);
}
for(int i = 0; i < 13; i++) {
pro[i] = 0;
}
// i表示2^12种可能性
for(int i = 0; i < (1 << 12); i++) {
double temp = 1.0;
int cnt = 0;
// j表示题目数
for(int j = 0; j < 12; j++) {
if((i >> j) & 1) {
temp *= pass[j];
cnt++;
} else {
temp *= (1 - pass[j]);
}
}
pro[cnt] += temp;
}
for(int i = 0; i < 13; i++) {
printf("%6lf\n", pro[i]);
}
return 0;
}