为什么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