P1291 [SHOI2002]百事世界杯之旅
题目描述
“……在2002年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字。只要凑齐所有百事球星的名字,就可参加百事世界杯之旅的抽奖活动,获得球星背包,随声听,更克赴日韩观看世界杯。还不赶快行动!”
你关上电视,心想:假设有n个不同的球星名字,每个名字出现的概率相同,平均需要买几瓶饮料才能凑齐所有的名字呢?
输入格式
整数n(2≤n≤33),表示不同球星名字的个数。
输出格式
输出凑齐所有的名字平均需要买的饮料瓶数。如果是一个整数,则直接输出,否则应该直接按照分数格式输出,例如五又二十分之三应该输出为(复制到记事本): 5+3/20 第一行是分数部分的分子,第二行首先是整数部分,然后是由减号组成的分数线,第三行是分母。减号的个数应等于分母的为数。分子和分母的首位都与第一个减号对齐。
分数必须是不可约的。
输入输出样例
输入 #1
2
输出 #1
3
思路
代码
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<bits/stdc++.h> using namespace std; int n; long long p,q=1,r; int C(long long x) { int p=0; while(x>0) { x/=10; p++; } return p; } long long gcd(long long a,long long b) { if(a<b) swap(a,b); if(a%b==0) return b; else return gcd(b,a%b); } int main() { scanf("%d",&n); for(int i=1; i<=n; i++) { p=p*i+q*n; q*=i; r=__gcd(p,q); p/=r; q/=r; } r=p/q; p%=q; if(p==0) { printf("%lld\n",r); return 0; } for(int i=1; i<=C(r); i++) printf(" "); printf("%lld\n",p%q); if(r>0) printf("%lld",r); for(int i=1; i<=C(q); i++) printf("-"); printf("\n"); for(int i=1; i<=C(r); i++) printf(" "); printf("%lld\n",q); return 0; }