九度oj1076N的阶乘

来源:互联网 发布:js判断离开当前页面 编辑:程序博客网 时间:2024/05/08 07:42

关于这个题:LRJ的书上有一种解法,于是我就原封不动的把那代码搬上去了,试试能不能AC,果然,超时了。

只好想改进的方法,我的方法大概是这样的:LRJ那段代码当中的核心主要是

1.那2个for loop模拟N!

2.从数组最后一个元素查到第一个不为0的元素就break;

在1里面,不管是2!还是900!里边的for统统都要从0更新到maxn-1,这样明显是低效率的。

用一个数flag控制每次要更新的范围,数小的时候就从0更新到对应的flag就好了。这样,1里面改进了。

在2里面,由于有了1的基础,比如一个数很小的时候,就可以不必从最后一个元素开始查找了,而可以从flag开始往前面查找了。这样,2改进了。

代码如下,我测试了几种flag的步长,步长为3的时候AC(和你对步长的定义也有关系,不绝对),为2的时候WA,主要原因应该是:比如1000!假设带了2000多个0,而步长为2的话每次只加2,并且加到最后可能还不够1000!应该有的位数。为此,我用2.5步长(i 变 2 次flag加 5)WA,用8/3步长(i 变 3 次就加 8)AC了。虽然麻烦,还是解决了。

代码如下,有步长为3和步长为8/3两种版本。。。

#include<iostream>using namespace std;#include<cstring>#define maxn 4000 int a[maxn]; int main(){    int inc,flag;    int n,s;    int i,j,k;     while(cin>>n)    {        memset(a,0,sizeof(a));        a[0]=1;        flag=0;         for(i = 2; i <= n; i++)        {                  inc=0;             if((flag+3) < maxn)                flag += 3;                                 for(j = 0; j < flag; j++)                {                    s = a[j]*i + inc;                    a[j] = s%10;                    inc = s/10;                }        }         for(k = flag ; k >= 0; k--)            if(a[k])                break;         for(int r = k; r >= 0; r--)            cout << a[r];        cout << "\n";    }    return 0;}/**************************************************************    Problem: 1076    User: true14fans    Language: C++    Result: Accepted    Time:1740 ms    Memory:1536 kb****************************************************************/


 

#include<iostream>using namespace std;#include<cstring>#define maxn 3000 int a[maxn]; int main(){    int inc,flag;    int n,s;    int i,j,k;     while(cin>>n)    {        memset(a,0,sizeof(a));        a[0]=1;        flag=0;         for(i = 2; i <= n; i++)        {                  inc=0;             if((flag+8) < maxn && (i+1)%3 == 0)                flag += 8;                                 for(j = 0; j <= flag; j++)                {                    s = a[j]*i + inc;                    a[j] = s%10;                    inc = s/10;                }        }         for(k = flag ; k >= 0; k--)            if(a[k])                break;         for(int r = k; r >= 0; r--)            cout << a[r];        cout << "\n";    }    return 0;}/**************************************************************    Problem: 1076    User: true14fans    Language: C++    Result: Accepted    Time:1400 ms    Memory:1532 kb****************************************************************/


 

原创粉丝点击