• 蓝桥杯:公倍数NYOJ 517


    为什么1小时有60分钟,而不是100分钟呢?这是历史上的习惯导致。 但也并非纯粹的偶然:60是个优秀的数字,它的因子比较多。 事实上,它是1至6的每个数字的倍数。即1,2,3,4,5,6都是可以除尽60。

    我们希望寻找到能除尽1至n的的每个数字的最小整数。

    不要小看这个数字,它可能十分大,比如n=100, 则该数为: 69720375229712477164533808935312303556800

    请编写程序,实现对用户输入的 n (n<100)求出1~n的最小公倍数。

    例如: 用户输入: 6 程序输出: 60

    用户输入: 10 程序输出: 2520

    要求考生把所有函数写在一个文件中。调试好后,存入与考生文件夹下对应题号的“解答.txt”中即可。 相关的工程文件不要拷入。 对于编程题目,要求选手给出的解答完全符合ANSI C标准,不能使用c++特性; 不能使用诸如绘图、中断调用等硬件相关或操作系统相关的API。

    本题满分:19分

    共4个用例:

    (2分) 输入: 3 输出: 6

    (3分) 输入: 16 输出: 720720

    (5分) 输入: 25 输出: 26771144400

    (9分) 输入: 77 输出: 410555180440430163438262940577600

    最小公倍数就是所有质数的相应幂的积
    比如N=10
    小于10的质数有2,3,5,7
    对应的最大幂是:3,2,1,1
    则最小公倍数是:2^3x3^2x5^1x7^1 = 2520

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cmath>
     4 using namespace std;
     5 
     6 int a[50] = {0};//存素数 
     7 bool vis[100];
     8 int b[50] = {0};//存幂次 
     9 
    10 void init_prim()//求小于100的所有素数存入数组a 
    11 {
    12      int i,j,k;
    13      int m = (int)(sqrt(100.0)+0.5);
    14      memset(vis,0,sizeof(vis));
    15      vis[0] = 1;
    16      vis[1] = 1;//必须加上,否则第一个素数别认为是1 
    17      for(i=2; i<=m; i++)
    18      if(!vis[i])
    19      {
    20           for(j=2*i; j<=100; j+=i)
    21                vis[j] = 1;
    22      }
    23      int t = 0;
    24      for(k=0; k<100; k++)
    25      if(!vis[k])
    26           a[t++] = k;
    27 }
    28      
    29 int main()
    30 {
    31      int i,j,k;
    32      init_prim();
    33      int n;
    34      //2^6 = 64,2^7 = 128;由于n最大100,幂次最大6 
    35     // for(i=0 ; i<100; i++)//素数没问题 
    36     // if(!vis[i])
    37     //      cout<<i<<endl;
    38    //  while(1);
    39      while(cin>>n)
    40      {
    41           memset(b,0,sizeof(b));
    42           for(i=0; i<=n&&a[i]<=n; i++)//”1到n素数个数小于n的一半 “不对,3有两个素数 
    43           {
    44               // cout<<a[i]<<"-----"<<endl;
    45                for(j=1; j<=6; j++)
    46                {
    47                     if(pow((double)a[i],(double)j)>(double)n)
    48                     {
    49                          b[i] = j -1;//b的下标不必新开  
    50                          break;
    51                     }
    52                     else if(pow((double)a[i],(double)j) == (double)n)//必须分开 
    53                     {
    54                           b[i] = j;
    55                          break;     
    56                     }
    57                }                                   
    58           }
    59           //不知道是不是pow函数的问题,把ans定义为int得出的结果出问题,double就对了 
    60           double ans = 1;
    61           for(k=0; k<i; k++)
    62           {
    63                //cout<<a[k]<<"........"<<b[k]<<endl;
    64                ans *= pow((double)a[k],(double)b[k]);
    65           }
    66           cout<<(int)ans<<endl;      
    67      }
    68      return 0;     
    69 }
    70 
    71 //该程序 到25时就溢出,ans换位long long前几个就错误啦,此时需要把pow函数换掉 

     下面是大数版程序(提交通过)

      

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 using namespace std;
     6 
     7 const int N = 105;
     8 int n;
     9 int a[N][50];
    10 int b[N] = {0};
    11 
    12 void multiply()
    13 {
    14     int i,j,k;
    15     memset(a,0,sizeof(a));
    16     for(i=3; i<=100; i++)
    17     {
    18         /*
    19         下面的是直接按平常的乘法,乘数的一位乘以被乘数的每一位并处理进位;另外是乘数整体乘以被乘数的每一位最后统一处理进位
    20         */
    21         int temp = 0; 
    22         a[i][0] = 1;//很重要 
    23         for(j=2; j<=i; j++)
    24         {
    25             int  c = 0; 
    26             for(k=0; k<50; k++)//最大不超过160位 ,安的是100!,最后除以3等50 
    27             {
    28                 temp = a[i][k]*b[j] + c;
    29                 a[i][k] = temp%1000;
    30                 c = temp/1000;
    31             }          
    32         }
    33     }
    34 }
    35 
    36 void printData(int n)
    37 {
    38     int i,j,k;
    39     for(i=49; i>=0; i--)
    40     if(a[n][i])
    41         break;
    42     cout<<a[n][i];//第一个不输出前导0 
    43     for(j=i-1; j>=0; j--)
    44         printf("%03d",a[n][j]);
    45     cout<<endl;   
    46 }
    47 
    48 int main()
    49 {
    50     int i, j, k;
    51     for(i=0; i<N; i++)
    52             b[i] = i;
    53     for(i=2; i<N; i++)
    54         for(j=i+1; j<=N; j++)
    55         {
    56             if(b[j]%b[i]==0)
    57                 b[j] /= b[i];
    58             //cout<<b[j]<<endl;
    59         }
    60     //for(i=0; i<100; i++)
    61       //  cout<<b[i]<<endl;
    62     //while(1);
    63     multiply();
    64     
    65     while(cin>>n)
    66     {
    67         
    68         if(n==1||n==2)
    69         {
    70             cout<<n<<endl;
    71             continue;
    72         }
    73         
    74         printData(n);
    75     }
    76     return 0;
    77 }
    78     
  • 相关阅读:
    一个创业成功者原始资本的快速积累
    个性创业先要聚人气才能赚大钱
    26个字母——女性必读
    100个成功创业经验方法谈
    从老板身上偷学的东西,你能吗?
    18岁29岁创业者的“黄金线” 要把握
    数禾云上数据湖最佳实践
    如何做好技术 Team Leader?
    闲鱼是怎么让二手属性抽取准确率达到95%+的?
    解读:云原生下的可观察性发展方向
  • 原文地址:https://www.cnblogs.com/hxsyl/p/2829916.html
Copyright © 2020-2023  润新知