[SHOI2002]百事世界杯之旅

题目描述

“……在2002年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字。只要凑齐所有百事球星的名字,就可参加百事世界杯之旅的抽奖活动,获得球星背包,随声听,更克赴日韩观看世界杯。还不赶快行动!”

你关上电视,心想:假设有n个不同的球星名字,每个名字出现的概率相同,平均需要买几瓶饮料才能凑齐所有的名字呢?

输入格式:

整数n(2≤n≤33),表示不同球星名字的个数。

输出格式:

如果输出是整数,那么直接输出一个整数
如果有分数,分数必须不可再约。 分3行打印 第一行是分子,前面有整数部分的位数
第二行是整数部分+分母位数个、‘-’
第三行是分母,前面有整数部分的位数
分数必须是不可约的。

输入样例#1:

2

输出样例#1:

3

概率期望+模拟

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,h;
pair<ll,ll> ans;
ll gcd(ll x,ll y)
{
	if(!y) return x;
	return gcd(y,x%y);
}
inline pair<ll,ll> add(ll a,ll b,ll c,ll d)
{
	ll x=b*c+a*d,y=a*c;
	ll g=gcd(x,y);
	x/=g,y/=g;
	return make_pair(y,x);
}
int main()
{
	ans.first=1;
	cin>>n;
	for(int i=1;i<=n;++i)
	{
		pair<ll,ll> t=add(ans.first,ans.second,n-i+1,n);
		ans.first=t.first;
		ans.second=t.second;
	}
	ll k=ans.second/ans.first,len=0;
	if(k*ans.first==ans.second)
	{
		cout<<k;
		return 0;
	}
	h=k;
	ans.second-=ans.first*k;
	while(k)
	{
		len++;
		k/=10;
	}
	ll len1=len;
	for(int i=1;i<=len;++i) cout<<" ";
	cout<<ans.second<<endl;
	cout<<h;
	len=0;ans.second=ans.first;
	while(ans.second)
	{
		len++;
		ans.second/=10;
	}
	for(int i=1;i<=len;++i) cout<<"-";
	cout<<endl;
	for(int i=1;i<=len1;++i) cout<<" ";
	cout<<ans.first;
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值