经典的求分数GCD和LCM的题目。方法:分别求出每个行星对于第一颗行星的相对速度,设其为ai/bi,那么答案就是乘上的一个最小的分数使得所有ai/bi与它相乘之后都为整数。那么这个分数就是:
(所有bi的LCM)
--------------
(所有ai的GCD)
用分解质因子的方法就可以求出这个分数了。注意要用高精度。
代码如下:
Program Astronomy;//By_Thispoet
Const
maxn=10000;
Type
arr=array[0..maxn]of Longint;
Var
i,j,k,m,n,tmp :Longint;
t,fz,fm :Array[0..maxn]of Longint;
map,num :Array[0..maxn]of Longint;
prime :Array[1..maxn*10]of Boolean;
ans :arr;
flag :Boolean;
Function Max(i,j:Longint):Longint;
begin
if i>j then exit(i);exit(j);
end;
Function Min(i,j:Longint):Longint;
begin
if i<j then exit(i);exit(j);
end;
Function Gcd(i,j:Longint):Longint;
begin
if j=0 then exit(i);
exit(Gcd(j,i mod j));
end;
Procedure Printf(i:Longint);
begin
if i>=1000 then write(i) else
if i>=100 then
begin
write(0);
write(i);
end else if i>=10 then
begin
write('00');
write(i);
end else
begin
write('000');
write(i);
end;
end;
Procedure Multiply(i:Longint;var p:arr);
var j,k:Longint;
begin
for j:=1 to p[0] do
p[j]:=p[j]*i;
j:=1;
while j<=p[0] do
begin
inc(p[j+1],p[j] div 10000);
p[j]:=p[j] mod 10000;
if p[p[0]+1]>0 then inc(p[0]);
inc(j);
end;
end;
Procedure Prime_Prepare;
begin
prime[1]:=false;
for i:=2 to maxn do
if prime[i] then
begin
inc(map[0]);
map[map[0]]:=i;
j:=i<<1;
while j<=maxn do
begin
prime[j]:=false;
inc(j,i);
end;
end;
end;
BEGIN
readln(n);
fillchar(prime,sizeof(prime),1);
Prime_Prepare;
while not eof do
begin
flag:=false;
t[0]:=0;
for i:=1 to n do read(t[i]);
for i:=2 to n do
begin
fz[i]:=t[i-1]*t[i];
fm[i]:=abs(t[i-1]-t[i]);
if fm[i]<>0 then
begin
tmp:=Gcd(fz[i],fm[i]);
fz[i]:=fz[i] div tmp;
fm[i]:=fm[i] div tmp;
end;
end;
fillchar(num,sizeof(num),0);
ans[0]:=1;ans[1]:=1;
for i:=2 to n do
begin
if fm[i]<>0 then
begin
for j:=1 to map[0] do
if fz[i]<map[j] then break else
begin
if fz[i] mod map[j]=0 then
begin
tmp:=0;
while fz[i] mod map[j]=0 do
begin
inc(tmp);
fz[i]:=fz[i] div map[j];
end;
num[j]:=Max(num[j],tmp);
end;
end;
end;
end;
for i:=1 to map[0] do
if num[i]>0 then
begin
if (not flag)and(not odd(map[i])) then
begin
dec(num[i]);
flag:=true;
end;
for j:=1 to num[i] do
Multiply(map[i],ans);
end;
fillchar(num,sizeof(num),127);
write(ans[ans[0]]);
for i:=ans[0]-1 downto 1 do
printf(ans[i]);
write(' ');
fillchar(ans,sizeof(ans),0);
ans[0]:=1;ans[1]:=1;
for i:=2 to n do
begin
if fm[i]<>0 then
begin
for j:=1 to map[0] do
begin
tmp:=0;
if fm[i] mod map[j]=0 then
begin
while fm[i] mod map[j]=0 do
begin
inc(tmp);
if tmp>=num[j] then break;
fm[i]:=fm[i] div map[j];
end;
end;
num[j]:=Min(num[j],tmp);
end;
end;
end;
for i:=1 to map[0] do
if num[i]<maxint then
begin
for j:=1 to num[i] do
Multiply(map[i],ans);
end;
if not flag then Multiply(2,ans);
write(ans[ans[0]]);
for i:=ans[0]-1 downto 1 do
printf(ans[i]);
writeln;
readln(n);
if n=0 then break;
end;
END.