Dice and Coin (Atcoder题目已翻译)

时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 256MB,其他语言 512MB

描述

Snuke有一个公平的N面骰子,可以等概率显示1到N的整数,还有一个公平的硬币。他将用它们玩下面的游戏:

  1. 掷骰子。当前得分就是掷骰子的结果。
  2. 只要分数在1和K−1(含)之间,就继续掷硬币。每次硬币正面朝上时,分数都会翻倍;如果硬币反面朝上,分数就会变成0。
  3. 当分数变成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;
}

谢谢支持!

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值