NYOJ 517 最小公倍数 (大数+求最小公倍数思想)

考虑到1-100的最小公倍数肯定超出__int64.所以需要转化成字符串问题来解

仔细观察会发现,【1-n】的最小公倍数,是【1-n-1】的最小公倍数乘以n的所有素因子中没有被【1-n-1】包含的素因子。

例如:【1-7】的最小公倍数是2*3*2*5*7,8=2*2*2,(8中2出现3次,【1-7】的素因子中只出现2次)那么【1-8】就是2*3*2*5*7*2

 

 1 //我的代码: 
 2  #include<stdio.h>
 3  #include<string.h>
 4  #define N 50
 5  int len,a[N]={1};
 6  char tab[100][45]={0,1};
 7  inline int gcd(int a,int b)
 8  {
 9      return b==0?a:gcd(b,a%b);
10  }
11  int mod(int t) //求余
12  {
13      int i,k;
14      for(k=0,i=len-1;i>=0;--i){
15          k=(k*10+a[i])%t;
16      }
17      return k;
18  }
19  void fun(int m,int n)  //乘以m再除以n
20  {
21      int i,j,k,c;
22      int s[N];
23      for(c=i=0;i<len+2;++i){
24          k=a[i]*m+c;
25          a[i]=k%10;
26          c=k/10;
27      }
28      for(i=len+1;i>=0&&!a[i];--i);
29      len=i+1;
30      for(k=j=0,i=len-1;i>=0;--i){
31          k=k*10+a[i];
32          s[j++]=k/n;
33          k%=n;
34      }
35      len=j;
36      memset(a,0,sizeof(a));
37      for(i=0;i<len;++i)
38          a[i]=s[len-i-1];
39      for(i=len;!a[i];--i);
40      len=i+1;
41  }
42  int main()
43  {
44      int i,j,k,t,n;
45      for(len=1,i=2;i<=100;++i){//打表
46          t=mod(i);
47          if(t){
48              k=gcd(i,t);
49              fun(i,k);
50          }
51          for(tab[i-1][0]=j=len-1;j>=0;--j)
52              tab[i-1][j+1]=a[j];
53      }
54      while(~scanf("%d",&n)){
55          for(j=tab[n-1][0]+1;j>0;--j)
56              printf("%d",tab[n-1][j]);
57          printf("\n");
58      }
59      return 0;
60  }
 1 //优秀代码: 
 2  #include <stdio.h>
 3  int a,i,j,l;
 4  void prime(int pri[])
 5  {
 6      for(i=2;i<=100;i++)
 7          if(!pri[i])
 8              for(j=i+i;j<=100;j+=i)
 9                  pri[j]=1;
10  }
11  void bingo(int ans[][45],int pri[])
12  {
13      for(a=3;a<=100;a++)  //打表
14      {
15          ans[a][0]=1;
16          for(i=2;i<=a;i++)
17          {
18              if(!pri[i])
19              {
20                  j=i;
21                  while(j<=a)
22                  {
23                      j*=i;
24                      int temp=0;
25                      for(l=0;l<50;l++)
26                      {
27                          int p=ans[a][l]*i+temp;
28                          ans[a][l]=p%10;
29                          temp=p/10;
30                      }
31                  }
32              }
33          }
34      }
35  }
36  int main()
37  {
38      int pri[100]={1,1,0},ans[101][45]={0};
39      prime(pri);
40      bingo(ans,pri);
41      while(scanf("%d",&a)!=EOF)
42      {
43          if(a==1||a==2)
44              printf("%d\n",a);
45          else
46          {
47              for(i=44;i>=0;i--)
48                  if(ans[a][i]) break;
49              for(j=i;j>=0;j--)
50                  printf("%d",ans[a][j]);
51              printf("\n");
52          }
53      }
54      return 0;
55  }

话不多说,这道题的测试数据有点弱了,我的方法是简单的最小公倍数求值,而上面的优秀代码是利用1~n中素数因子幂最大的拿出来相乘,不过总的说过来我感觉还是我的比较省时!!

 

 

posted on 2012-08-10 19:46  mycapple  阅读(848)  评论(0编辑  收藏  举报

导航