题目背景
本市的某神校里有一个学霸,他的名字叫小明(为了保护主人公的隐私,他的名字都用“小明”代替)。在这次的期中考试中,小明同学走桃花运,在考场上认识了一位女生,她的名字叫小红(同样是为了保护隐私)。
题目描述
英语考试结束了,打完铃,她就主动来找小明说话,一来就要借英语卷子对答案。小明是公认的英语大神,二话不说就把卷子借给了她。小红对了一遍答案,简直是千差万别,她不禁冒出了冷汗。这时,小明走过来,安慰她:“没事,我又不是标准答案,不一定全对。”
已知小明答案的准确率是A%,一共有N道题,给出小红对答案的结果S(一个长为N的01串,其中1表示两人答案一样,0表示不一样)。为了简化问题,所有题目都是判断题。
请你帮小红写一个程序,计算出她对Q题及以上的概率。
(P.S.小明后来把那张卷子送给了小红,别想多了,不是定情信物)
输入格式
第1行,三个正整数N,A,Q。
第2行,一个01字符串S。
输出格式
一行,一个实数,表示她对Q题及以上的概率。(保留3位小数)
输入输出样例
输入 #1
3 90 2 100
输出 #1
0.172
说明/提示
对于90%数据,N<=50,N-5<=Q<=N。
对于剩下的10%数据,N<=10000,Q=0.
从p开始枚举,也就是从正好做对p到题,枚举到做对全部题。
做对的题 = 两人相同的正确题 + 两人不同而小红做对的题。
至于式子纯属就是二项分布的式子了。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; int n,a,q,com,unc; double rt,p; char s[6666]; long long c[222][333]; int main(){ scanf("%d%d%d",&n,&a,&q); scanf("%s",s+1); if(n>50){ printf("1.000"); return 0; } rt=(double)a/(double)100; c[0][0]=c[1][1]=c[1][0]=1; for(int i=1; i<=50; i++){ c[i][0]=c[i][i]=1; for(int j=1; j<i; j++){ c[i][j]=c[i-1][j]+c[i-1][j-1]; } } for(int i=1; i<=strlen(s+1); i++){ if(s[i]=='1'){ com++; } else if(s[i]=='0'){ unc++; } } for(int i=q; i<=strlen(s+1); i++){ for(int j=0; j<=i; j++){ int ncom=j,nunc=i-j; if(ncom>com||nunc>unc){ continue; } double p1=c[com][ncom]*pow(rt,ncom)*pow(1-rt,com-ncom); double p2=c[unc][nunc]*pow(1-rt,nunc)*pow(rt,unc-nunc); p=p+p1*p2; } } printf("%.3lf",p); return 0; }