题目描述
为什么 1 小时有 60 分钟,而不是 100 分钟呢?这是历史上的习惯导致。
但也并非纯粹的偶然:60 是个优秀的数字,它的因子比较多。
事实上,它是 1 至 6 的每个数字的倍数。即 1,2,3,4,5,6 都是可以除尽 60。
我们希望寻找到能除尽 1 至 nn 的的每个数字的最小整数。
不要小看这个数字,它可能十分大,比如 nn = 100, 则该数为:
69720375229712477164533808935312303556800
输入描述
输入一个数字 N\ (N<100)N (N<100)。
输出描述
输出出 1 ~ nn 的最小公倍数。
输入输出样例
示例
输入
6
输出
60
算法思想:
最小公倍数的n项公式可以从n-1项推广。
a1,a2,a3……an的最小公倍数为a1,a2,a3……an-1的最小公倍数和an的最小公倍数
举个栗子,1,2,3,4,5的最小公倍数为60,1,2,3,4,5,6的最小公倍数为60和6的最小公倍数的结果还是60.
所以1,2,3,4,5,6的最小公倍数为60
我们把所有的数进行质因数分解:1 2 3 2 * 2 5 2 * 3将结果作为一个容器,把所有数对应的贡献度算出来。
define 贡献度(ai) 与之前所有i-1个数做一个运算:若贡献度(ai)%贡献度(ai-1)==0 则贡献度(ai)/=贡献度(ai-1)
结果为所有数的贡献度之积。
若有 2 4 8 16 32 等5个数求最小公倍数,则贡献度(2)=2。贡献度(4)=4/贡献度(2)=2。贡献度(8)=8/贡献度(4)/贡献度(2)=2,以此类推则都是2
因此2 4 8 16 32的最小公倍数为2 * 2 * 2 * 2 * 2=32
答案最高超过了18位(unsigned long long)所以又要整个高精度乘法。
代码如下
#include <bits/stdc++.h>
using namespace std;
int prime[101];
void primee()
{
for (size_t i = 1; i <= 100; i++)
{
prime[i] = i;
}
for (size_t i = 2; i <= 100; i++)
{
for (size_t j = 2; j <= i - 1; j++)
{
if (prime[i] % prime[j] == 0)
{
prime[i] /= prime[j];
}
}
}
}
int main()
{
int n;
primee();
while (cin >> n)
{
int num[101] = {0}, len = 1;
num[1]=1;
for (size_t i = 1; i <= n; i++)
{
for (size_t j = 1; j <= len; j++)
{
num[j] *= prime[i];
}
for (size_t j = 1; j <= len; j++)
{
num[j + 1] += num[j] / 10;
num[j] %= 10;
}
while (num[len + 1])
{
len++;
num[len + 1] += num[len] / 10;
num[len] %= 10;
}
}
for (int i = len; i >= 1; i--)
{
cout << num[i];
}
cout<<endl;
}
return 0;
}