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中素数因子幂最大的拿出来相乘,不过总的说过来我感觉还是我的比较省时!!

 

 

你可能感兴趣的:(思想)