【SHOI 2002】百事世界杯之旅 (BSOI4841)
2017-08-04 20:29
381 查看
【SHOI 2002】百事世界杯之旅
Description
……在2003年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字。只要凑齐所有百事球星的名字,就可以参加百事世界杯之旅的抽奖活动,获取球星背包、随身听,更可以赴日韩观看世界杯。还不赶快行动!……”
你关上电视,心想:假设有n个不同球星的名字,每个名字出现的概率相同,平均需要买几瓶饮料才能凑齐所有的名字呢?
Input
输入一个数字n,2≤n≤33,表示不同球星名字的个数。
Output
输出凑齐所有的名字平均需要购买的饮料瓶数。如果是一个整数则直接输出。否则就用下面样例中的格式分别输出整数部分和小数部分。分数必须是不可约的。
Sample Input
5
Sample Output
11(5/12)
Hint
输出说明:先输出整数部分,若有小数部分,用括号把不可约分式括起来
思路:
分析 这是一道比较简单的概率和期望问题。只要确定好计算方法,就可以很容易的得到公式。如果单独考虑每一名球星,那么就中了命题人的圈套。因为考虑单独的一个球星的时候所买的“没用”的饮料在考虑其他球星的时候可能会变成有用的。正确的思路是,假设现在已经有k个球星的名字,那么要使球星的名字达到k+1个平均需要买多少瓶饮料?这是很容易计算的。 我们可以知道,第一个球星抽到的概率是1,第n个是1/n。那么我们要从k个到k+1个球星的概率为(n-k)/n,所以期望为n/(n-k)。所以我们从没有球星的名字开始,直到把所有的球星名字都凑齐,平均需要的饮料数(E)就可以计算出来:
ANS=n(1/1+1/2+1/3+....1/n)
由于题目的数据规模并不大,所以可以直接使用PASCAL的Comp或Int64(C/C++的long long)进行计算。而题目要求得到即约分数,只要在计算的时候使用分数并注意约分就可以了。
如果n很大,就要用公式 : 0.57721566490153286060651209 + ln(n)
(参与分数计算的都要开long long,整型一定会爆。。。)
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
#define pi acos(-1)
#define endl '\n'
#define srand() srand(time(0));
#define me(x,y) memset(x,y,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
#define close() ios::sync_with_stdio(0); cin.tie(0);
#define FOR(x,n,i) for(int i=x;i<=n;i++)
#define FOr(x,n,i) for(int i=x;i<n;i++)
#define W while
#define sgn(x) ((x) < 0 ? -1 : (x) > 0)
#define bug printf("***********\n");
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,0,1,0,1,-1,-1,1};
const int dy[]={0,1,0,-1,-1,1,-1,1};
const int maxn=1000;
const int maxx=1e7+100;
const double EPS=1e-7;
const int mod=998244353;
template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}
template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}
template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
template<class T> void Scan(T &x)
{
static int CH;
while((CH=getchar())<'0'||CH>'9');
for(x=CH-'0';(CH=getchar())>='0'&&CH<='9';x=(x<<3)+(x<<1)+(CH-'0'));
}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.out" , "w" , stdout );
//cerr << "run time is " << clock() << endl;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
LL a=1,b=1;
for(LL i=2;i<=n;i++)
{
a=a*i+b;
b*=i;
LL r=__gcd(a,b);
a/=r;b/=r;
}
a*=n;
if(a%b==0)
cout<<a/b<<endl;
else
{
LL temp=__gcd(a,b);
a/=temp;b/=temp;
LL r=a/b;
a=a-(b*r);
cout<<r<<"("<<a<<"/"<<b<<")"<<endl;
}
}
}
Description
……在2003年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字。只要凑齐所有百事球星的名字,就可以参加百事世界杯之旅的抽奖活动,获取球星背包、随身听,更可以赴日韩观看世界杯。还不赶快行动!……”
你关上电视,心想:假设有n个不同球星的名字,每个名字出现的概率相同,平均需要买几瓶饮料才能凑齐所有的名字呢?
Input
输入一个数字n,2≤n≤33,表示不同球星名字的个数。
Output
输出凑齐所有的名字平均需要购买的饮料瓶数。如果是一个整数则直接输出。否则就用下面样例中的格式分别输出整数部分和小数部分。分数必须是不可约的。
Sample Input
5
Sample Output
11(5/12)
Hint
输出说明:先输出整数部分,若有小数部分,用括号把不可约分式括起来
思路:
分析 这是一道比较简单的概率和期望问题。只要确定好计算方法,就可以很容易的得到公式。如果单独考虑每一名球星,那么就中了命题人的圈套。因为考虑单独的一个球星的时候所买的“没用”的饮料在考虑其他球星的时候可能会变成有用的。正确的思路是,假设现在已经有k个球星的名字,那么要使球星的名字达到k+1个平均需要买多少瓶饮料?这是很容易计算的。 我们可以知道,第一个球星抽到的概率是1,第n个是1/n。那么我们要从k个到k+1个球星的概率为(n-k)/n,所以期望为n/(n-k)。所以我们从没有球星的名字开始,直到把所有的球星名字都凑齐,平均需要的饮料数(E)就可以计算出来:
ANS=n(1/1+1/2+1/3+....1/n)
由于题目的数据规模并不大,所以可以直接使用PASCAL的Comp或Int64(C/C++的long long)进行计算。而题目要求得到即约分数,只要在计算的时候使用分数并注意约分就可以了。
如果n很大,就要用公式 : 0.57721566490153286060651209 + ln(n)
(参与分数计算的都要开long long,整型一定会爆。。。)
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
#define pi acos(-1)
#define endl '\n'
#define srand() srand(time(0));
#define me(x,y) memset(x,y,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
#define close() ios::sync_with_stdio(0); cin.tie(0);
#define FOR(x,n,i) for(int i=x;i<=n;i++)
#define FOr(x,n,i) for(int i=x;i<n;i++)
#define W while
#define sgn(x) ((x) < 0 ? -1 : (x) > 0)
#define bug printf("***********\n");
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,0,1,0,1,-1,-1,1};
const int dy[]={0,1,0,-1,-1,1,-1,1};
const int maxn=1000;
const int maxx=1e7+100;
const double EPS=1e-7;
const int mod=998244353;
template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}
template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}
template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
template<class T> void Scan(T &x)
{
static int CH;
while((CH=getchar())<'0'||CH>'9');
for(x=CH-'0';(CH=getchar())>='0'&&CH<='9';x=(x<<3)+(x<<1)+(CH-'0'));
}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.out" , "w" , stdout );
//cerr << "run time is " << clock() << endl;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
LL a=1,b=1;
for(LL i=2;i<=n;i++)
{
a=a*i+b;
b*=i;
LL r=__gcd(a,b);
a/=r;b/=r;
}
a*=n;
if(a%b==0)
cout<<a/b<<endl;
else
{
LL temp=__gcd(a,b);
a/=temp;b/=temp;
LL r=a/b;
a=a-(b*r);
cout<<r<<"("<<a<<"/"<<b<<")"<<endl;
}
}
}
相关文章推荐
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- P1291 [SHOI2002]百事世界杯之旅
- 【SHOI 2002】百事世界杯之旅 概率期望
- COGS 1224. [SHOI2002]百事世界杯之旅(期望概率)
- ●洛谷P1291 [SHOI2002]百事世界杯之旅
- [SHOI2002]百事世界杯之旅
- [SHOI2002]百事世界杯之旅(概率期望+Refun的胡策)