HDU5139 Formula && BestCoder Round #21 1002

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5139

题思路:BestCoder官方题解:

找规律
f(1)=1
f(2)=1*1*2=(1)*(1*2)=1!*2!
f(3)=1*1*1*2*2*3=(1)*(1*2)*(1*2*3)=1!*2!*3!

式子可以简化为 
  
  
   
   f(n)=i=1n(n!)%MOD
  
  ,直接打表不行,会超内存,可以对数据进行离线处理。排好序之后从小到大暴力。ClogC+10000000 ,C为case数目。
说一说,我对这题的感受吧,其实当时比赛时,我已经找出了这规律了,但还是:要么超内存,要么超时间。直到比赛 结束以后,看了官方题解和别人的代码后,我才知道,还有离线处理这个东西(竟然可以先将数据一次性全输入,然后再进行全部的运算),这回真是长见识了。

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

typedef __int64 ll;
const int maxn=100010;
const int MOD=1000000007;

struct node
{
    int n,id,ans;
}no[maxn];

bool cmp1(node a,node b)
{
    return a.n<b.n;
}

bool cmp2(node a,node b)
{
    return a.id<b.id;
}

int main()
{
    int cnt=0,n;
    while (scanf("%d",&n)!=EOF)
    {
        cnt++;
        no[cnt].id=cnt;
        no[cnt].n=n;
    }                           //很奇怪是不是,这就是题解所谓的对数据进行离线处理
    sort(no+1,no+cnt+1,cmp1);
    int a=1,b=1,i,j=1;
    for (i=1;i<=no[cnt].n;i++)
    {
        a=(ll)a*i%MOD;          //相当于阶乘
        b=(ll)b*a%MOD;          //相当于n个阶乘相乘
        while (j<=cnt&&i==no[j].n)
            no[j++].ans=b;
    }
    sort(no+1,no+cnt+1,cmp2);
    for (i=1;i<=cnt;i++)
        printf("%d\n",no[i].ans);

    return 0;
}

Time Limit Exceeded:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;

typedef __int64 ll;
const int MOD=1000000007;
const int maxn=10000005;
ll f[maxn];

int main()
{
    int i,j;
    f[1]=1;
    for(i=2;i<=101;i++)
        f[i]=(f[i-1]*i)%MOD;
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        ll ans=1;
        for(i=1;i<=n;i++)
            ans=(ans*f[i])%MOD;
        printf("%I64d\n",ans);
    }
    return 0;
}

Memory Limit Exceeded:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;

typedef __int64 ll;
const int MOD=1000000007;
const int maxn=10000005;
ll f[maxn];

int main()
{
    int i,j;
    f[1]=1;
    for(i=2;i<=10000005;i++)
        f[i]=(f[i-1]*i)%MOD;
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        ll ans=1;
        for(i=1;i<=n;i++)
            ans=(ans*f[i])%MOD;
        printf("%I64d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值