这道题当时盯着看了十分钟也没有一点头绪,还是我太菜了,于是上网寻找求最小公倍数方法
题目
Problem-2028
Problem Description
求n个数的最小公倍数。
Input
输入包含多个测试实例,每个测试实例的开始是一个正整数n,然后是n个正整数。
Output
为每组测试数据输出它们的最小公倍数,每个测试实例的输出占一行。你可以假设最后的输出是一个32位的整数。
Sample Input
2 4 6
3 2 5 7
Sample Output
12
70
方法
查阅WIKI百科可知,最小公倍数=两个整数的/这两个数的最大公因数
https://zh.wikipedia.org/wiki/最小公倍數#与最大公因数之关系
这个公式我还没搞明白……
先求最大公因数,可以使用辗转相除法或更相减损术来求。
http://www.cnblogs.com/santiego/p/9568208.html
辗转相除法的证明
为什么除数和余数的最大公约数就是被除数和除数的最大公约数?
试证:被除数A与除数B,且A>B,和它们的余数R的最大公约数相同
证明:由题意可设,
A
=
q
B
+
R
(
q
∈
N
+
)
,
0
<
R
<
B
A=qB+R(q∈N+),0<R<B
A=qB+R(q∈N+),0<R<B
设
A
A
A,
B
B
B最大公约数为
d
d
d,记为
d
=
(
A
,
B
)
d=(A,B)
d=(A,B)
先证d为B与R的公因数
设
m
,
n
∈
N
+
m,n∈N+
m,n∈N+,使
A
=
m
d
,
B
=
n
d
A=md,B=nd
A=md,B=nd
R
=
A
−
q
B
=
m
d
−
q
n
d
=
d
(
m
−
q
n
)
R=A-qB=md-qnd=d(m-qn)
R=A−qB=md−qnd=d(m−qn)
∴
R
R
R能被
d
d
d整除,即
d
d
d为
R
R
R的因数
再证
d
d
d为
B
B
B和
R
R
R的最大公因数,即证
d
=
(
B
,
R
)
d=(B,R)
d=(B,R)
反证法:假设存在
D
D
D,使
(
B
,
R
)
=
D
>
d
(B,R)=D>d
(B,R)=D>d
∵
A
=
q
B
+
R
∵A=qB+R
∵A=qB+R
∴
∴
∴D能整除
A
A
A且
D
D
D能整除
B
B
B
∴
D
∴D
∴D能整除
(
A
,
B
)
=
d
(A,B)=d
(A,B)=d
推出
D
≤
d
D≤d
D≤d,与假设矛盾
∴
∴
∴不存在
(
B
,
R
)
=
D
>
d
(B,R)=D>d
(B,R)=D>d
即
d
d
d为
B
B
B和
R
R
R的最大公因数
∴
(
A
,
B
)
=
(
B
,
R
)
=
d
∴(A,B)=(B,R)=d
∴(A,B)=(B,R)=d
可以看出该性质可以传递
(
A
,
B
)
=
(
B
,
A
%
B
)
=
(
A
%
B
,
B
%
(
A
%
B
)
)
=
…
=
(
d
,
0
)
(A,B)=(B,A\%B)=(A\%B,B\%(A\%B))=…=(d,0)
(A,B)=(B,A%B)=(A%B,B%(A%B))=…=(d,0)
所以当最后余数为0时,除数即为最大公约数
d
d
d
给出
A
>
B
A>B
A>B,求最大公因数,可以得递推公式
f
(
A
,
B
)
=
{
A
B
=
0
f
(
B
,
A
%
B
)
B
>
0
f(A,B)= \begin{cases} A & B = 0 \\ f(B,A\%B)& B>0 \end{cases}
f(A,B)={Af(B,A%B)B=0B>0
证明最小公倍数=两数之积/最大公约数
(这部分思路参考了一位数学系的同学,他跟我说不知道咋证就显然)
设
d
=
(
A
,
B
)
,
M
d=(A,B),M
d=(A,B),M为
A
,
B
A,B
A,B最小公倍数,记
M
=
[
A
,
B
]
M=[A,B]
M=[A,B]
令
A
=
m
d
,
B
=
n
d
,
A=md,B=nd,
A=md,B=nd,且
m
,
n
∈
N
+
m,n∈N+
m,n∈N+
存在
M
=
p
A
=
q
B
,
且
p
,
q
∈
N
+
,
(
p
,
q
)
=
1
M=pA=qB ,且p,q∈N+,(p,q)=1
M=pA=qB,且p,q∈N+,(p,q)=1
∵
M
∵M
∵M能被
A
=
m
d
A=md
A=md整除,
M
M
M能被
B
=
n
d
B=nd
B=nd整除,
(
m
,
n
)
=
1
(m,n)=1
(m,n)=1
显然
m
n
d
mnd
mnd为
A
,
B
A,B
A,B公倍数,设
N
N
N为
A
,
B
A,B
A,B的任一公倍数
则
m
n
d
mnd
mnd一定能整除
N
N
N,推得
m
n
d
mnd
mnd为
A
A
A与
B
B
B的最小公倍数
∴
[
A
,
B
]
=
m
n
d
=
(
A
∗
B
)
/
d
∴[A,B]=mnd= (A*B)/d
∴[A,B]=mnd=(A∗B)/d
代码
#include<stdio.h>
long long gcd(long long a,long long b);
long long lcm(long long a,long long b);
int main(void)
{
int n;
long long next;
while(scanf("%d",&n)==1){
long long commul=1;
while(n-->0){
scanf("%lld",&next);
commul=lcm(commul,next);
}
printf("%lld\n",commul);
}
return 0;
}
long long gcd(long long a,long long b)//返回a,b最大公约数
{
long long r;
if(a<b){
r=b;
b=a;
a=r;
}
while((r=a%b)!=0){
a=b;
b=r;
}
return b;
}
long long lcm(long long a,long long b)//返回a,b的最小公倍数
{
long long multi=a*b;
return multi/gcd(a,b);
}
按照题目的意思,进行乘法运算一定会溢出。
之前两次使用强制转换怎么改还是WA,一怒之下全部换成了long long,终于AC了
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
---|---|---|---|---|---|---|---|---|
28719269 | 2019-03-27 18:40:05 | Accepted | 2028 | 15MS | 1692K | 608 B | C | Overstars |
28719245 | 2019-03-27 18:38:24 | Wrong Answer | 2028 | 0MS | 1696K | 588 B | C | Overstars |
28719220 | 2019-03-27 18:36:12 | Wrong Answer | 2028 | 31MS | 1700K | 514 B | C | Overstars |
也不知道这道题花了这么多时间值不值。
好了,今天晚上去图书馆把DP入个门……
大物也得稍微自学下……
2019年3月27日18点44分