蓝桥杯试题集试题总汇(C++)
问题描述
某个抽卡游戏卡池抽出限定卡的概率为p,该游戏有一个“井”的机制,抽满k次卡后直接送这张限定卡。试求获得这张限定卡需要的期望抽卡次数。输入为一行,用空格隔开的p和k。输出为一行,即期望抽卡次数,取2位小数
样例输入
0.005 250
样例输出
142.88
样例说明
第1次抽到的概率为0.005
第2次抽到的概率为(1-0.005)*0.005
第n次抽到的概率为(1-0.005)^(n-1)*0.005
第250抽到的概率为之前都没有抽到的概率,即(1-0.005)^249
最终结果
1*0.005+2*(1-0.005)*0.005+…+n*(1-0.005)^(n-1)*0.005+…+250*(1-0.005)^249=142.88
数据规模和约定
请使用double类型存储所有浮点数变量
对60%的测试点,保证k≤1000,
对100%的测试点,保证k≤1000000。
如果程序过于低效,在k较大时会因超时而错误。
分析
这道题的思路完全可以按照样例说明的思路,直接编写相应代码就OK了。但有大佬提出了这道题另一种令人拍案叫绝的方法,用秦九韶算法。下面图片是秦九韶算法的一个说明。
参考代码
代码1,常规思路
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
double getEveryP(double p,int i)
{
double sumcase=i*pow(1-p,i-1)*p;
return sumcase;
}
int main()
{
double p;
int k;
cin>>p>>k;
double sum=0;
for(int i=1;i<k;i++)
{
sum=sum+getEveryP(p,i);//记录每一次
}
double last=k*pow(1-p,k-1);//记录最后一次
sum=sum+last;
printf("%.2lf",sum);
return 0;
}
代码2,秦九韶算法
#include<iostream>
#include <stdio.h>
using namespace std;
double qjzsf(double p,int k)
{
double result=k;
for(int i=k;i>=2;i--)
{
result=result*(1-p)+(i-1)*p;
}
return result;
}
int main()
{
int k;
double p;
cin>>p>>k;
double sum = 0;
sum = qjzsf(p,k);
printf("%.2lf\n",sum);
return 0;
}