hdu1099

有一段时间没做ACM了,都有些忘了,现在捡起来再练练手。这是一道数学题目,出题者的英文真是恶心得不得了,这题的意思说的真是让人不容易明白。我也是读了好久,然后不确定,就看了下别人的理解,下面贴一个别人的理解:
这道题的意思说得糊里糊涂的……大概意思是这样吧(反正按以下理解能做出AC code):一套彩票有n张,编号由1到n,凑齐这n张能得奖,问平均每买几张彩票会得到完整的一套彩票。(不是直译,这只是我理解的题目的大意,注意“平均每买几张……”),这大概是一个数学期望的问题吧。以n=3为例,要凑齐1、2和3,买一张彩票无论是1、2还是3都是所需的,买中所需彩票的概率是1,期望的买的张数也是1;再买一张,现在需要的是2或3,一次买中所需的彩票的概率为2/3,忽略张数是int,假设平均每买x张(不是每买x张就一定有,而是平均)就能得到所需的,有(2/3)*x=1,于是x=1/(2/3);假设得到2,现在需要3,买一张是3的概率是1/3,显然平均每买1/(1/3)=3张就有一张3.所以sum=1+1/(2/3)+1/(1/3)。


题意明白了,下面就是我们要看的答案就是求:n/1+n/2+n/3+----+n/n!,这个式子是一个发散的,n无穷大的时候,结果无限大,这个是没有一个公式的,所以题目规定的1<=n<=22就是这个意思,那么我们通分之后分母是n!,22!也会超过long long所以直接算肯定是不行的,那么我们想通分,通分,不就是求最小公倍数?对了,求所有的数字的最小公倍数就不会超了,你可以看10,20一下子就小了10倍,算一下肯定不会超得。
#include<iostream>
using namespace std;
long long  gcd(long long a , long long b)    //分子,分母约分
{
    if(b==0)return a;
    return gcd(b,a%b);
}
int main()
{
    long long sum1,sum2,i,k,num;
    int j1,j2;
    long long N;
    while(cin>>N)
    {
        j1=j2=0;
        sum1=1;
        sum2=0;
        k=0;
        if(N==1){cout<<"1"<<endl;continue;}
        if(N==2){cout<<"3"<<endl;continue;}
        for(i=1;i<=N;i++)
            sum1=sum1*i/gcd(sum1,i);                        //最小公倍数等于成绩除以最大公约数
        for(i=1;i<=N;i++)
            sum2+=sum1/i;
        sum2*=N;
        k=sum2/sum1;                                              //整数部分
        if(sum2%sum1==0)cout<<k<<endl;
        else
        {
            num=sum2%sum1;
            i=gcd(sum1,num);
            num/=i;
            sum1/=i;
            i=k;
            while(i/10!=0)                                    //算整数部分的位数,需要空格的
            {
                i/=10;
                j1++;
            }
        for(i=0;i<=j1+1;i++)
            cout<<" ";
        cout<<num<<endl;
        cout<<k<<" ";
        i=sum1;
        while(i/10!=0)                                         //算分母的位数同上
        {
            i/=10;
            j2++;
        }
        for(i=0;i<=j2;i++)
            cout<<"-";
        cout<<endl;
        for(i=0;i<=j1+1;i++)
            cout<<" ";
        cout<<sum1<<endl;
        }
    }
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值