poj 3101 Astronomy——求分数的最小公倍数

已知n个点的环绕点X的周期,求出各点转到同一直线上的最短时间。

求出相邻点间相距半圈所需时间=追及时间/2。求出各个半圈时间的最小公倍数为结果

公式:T[i] = d[i]*d[i+1] / (d[i+1]-d[i])*2

那么以读入的第一个点为基准点,求出以后所有点和第一个点相聚半圈所需的时间,求出这几个分数的最小公倍数就可以了。(和第一个点所用的时间相同就不用计算了)

分数的最小公倍数求法:设两分数为a/b,c/d(已化为最简形式),则最小公倍数为:lcm(a,c)/gcd(b,d)

所以在每读一个周期的时候先把公式化为最简形式,再分别对分子分母求lcm和gcd

a27400 3101 Accepted 5452K 3344MS Java 1616B 2011-09-07 12:41:57
import java.io.BufferedInputStream;
import java.util.*;
import java.math.*;
public class Main
{
public static int[] p=new int[3000];
public static int top;
public static int[] a=new int[3000];
public static boolean[] isprime=new boolean[10001];
public static void init()
{
int i,j;
for(i=2;i<=10000;i++)
{
if(!isprime[i]) p[top++]=i;
for(j=0;j<top&&i*p[j]<=10000;j++)
{
isprime[i
*p[j]]=true;
if(i%p[j]==0) break;
}
}
top
--;
isprime[
1]=true;
}
public static void solve(int k)
{
for(int i=0;i<=top&&p[i]<=k;i++)
{
int temp=0;
while(k%p[i]==0)
{
temp
++;
k
/=p[i];
}
if(temp>a[i])
a[i]
=temp;
}
}
public static int gcd(int x1,int x2)
{
if(x2==0)
return x1;
return gcd(x2,x1%x2);
}
public static void main(String[] args)
{
Scanner cin
=new Scanner(new BufferedInputStream(System.in));
init();
int n=cin.nextInt();
int[] q=new int[1000];
int[] sub=new int[1000];
q[
0]=cin.nextInt();
for(int i=1;i< n;i++)
{
q[i]
=cin.nextInt();
int temp=Math.abs(q[i]-q[0]);
if(temp!=0)
{
int Gcd=gcd(q[i]*q[0],temp);
temp
=temp/Gcd;
sub[i]
=temp;
solve(q[i]
*q[0]/Gcd);
}
}
BigInteger ans1
=BigInteger.ONE;
for(int i=0;i<=top;i++)
for(int j=0;j<a[i];j++)
ans1
=ans1.multiply(BigInteger.valueOf(p[i]));
int ans2=0;
for(int i=1;i< n;i++)
ans2
=gcd(ans2,sub[i]);
if(a[0]>0)
ans1
=ans1.divide(BigInteger.valueOf(2));
else ans2*=2;
if(ans2==0)
ans1
=BigInteger.ZERO;
System.out.println(ans1
+" "+ans2);
}
}

  

你可能感兴趣的:(poj)