时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 256MB,其他语言 512MB
描述
Snuke有一个公平的N面骰子,可以等概率显示1到N的整数,还有一个公平的硬币。他将用它们玩下面的游戏:
- 掷骰子。当前得分就是掷骰子的结果。
- 只要分数在1和K−1(含)之间,就继续掷硬币。每次硬币正面朝上时,分数都会翻倍;如果硬币反面朝上,分数就会变成0。
- 当分数变成0或变成K或以上时,游戏结束。如果分数为K或以上,Snuke 获胜;如果分数为0,Snuke 输。
给你N和K。求Snuke赢得比赛的概率。
输入描述
N K
输出描述
打印 Snuke 赢得游戏的概率。当绝对误差或相对误差不超过 10−9 时,输出结果被认为是正确的。
用例输入 1
3 10
用例输出 1
0.145833333333
用例输入 2
100000 5
用例输出 2
0.999973749998
提示
限制因素
- 1≤N≤105
- 1≤K≤105
- 所有输入值均为整数。
样本输出 1
- 如果骰子显示1,Snuke需要在四次掷硬币中连续得到四个头,才能得到10或以上的分数。发生这种情况的概率是 31×(21)4=481。
- 如果骰子显示2,Snuke需要在三次掷硬币中连续得到三个人头才能获得10或以上的分数。发生这种情况的概率是31×(21)3=241。
- 如果骰子显示3,Snuke需要在两次掷硬币中连续得到两个 “头”,才能获得10或以上的分数。发生这种情况的概率是31×(21)2=121。
因此,Snuke获胜的概率是481+241+121=487≃0.1458333333。
AC代码:
#include<bits/stdc++.h>
using namespace std;
double res;
int main(){
int n,k;
cin >> n >> k;
for(int i = 1;i <= n;i++){
if(i > k){
res += (1.0) / (double)n;
}else{
int a = log2(k / i);
if(i * pow(2,a) != k)
a = a + 1;
res += (1.0) / (double)(n * pow(2,a));
}
}
cout << fixed << setprecision(12) << res;
return 0;
}