经典的求分数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.