poj 3101 Astronomy

Astronomy
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 4932 Accepted: 1065

Description

There are n planets in the planetary system of star X. They orbit star X in circular orbits located in the same plane. Their tangent velocities are constant. Directions of orbiting of all planets are the same.

Sometimes the event happens in this planetary system which is called planet parade. It is the moment when all planets and star X are located on the same straight line.

Your task is to find the length of the time interval between two consecutive planet parades.

Input

The first line of the input file contains n — the number of planets (2 ≤ n ≤ 1 000).

Second line contains n integer numbers ti — the orbiting periods of planets (1 ≤ ti ≤ 10 000). Not all of ti are the same.

Output

Output the answer as a common irreducible fraction, separate numerator and denominator by a space.

Sample Input

3
6 2 3

Sample Output

3 1

Hint


分析:设两个飞船的周期为a,b(a<b),我们以半圈为一个长度单位,则两个飞船在单位时间内错开的长度差为l = 2*(1/a – 1/b),只有当所有这样的长度差均为整数时,所有的飞船才会在同一直线上。

    假设第i个飞船与第i+1个飞船的长度差为l(i)(1<=i<=n-1),则只需要求一个最小的分数d,使得d*l(i)均为整数  (1<=i<=n-1)。其实d就是l(i)的倒数的最小公倍数,因为它和每一个1/l(i)的商都是整数。

    分数的最小公倍数:分数u1,u2…un的最小公倍数定义为最小的分数d,使得d/u1,d/u2…d/un均为整数。这个d即为ui分子的最小公倍数除以分母的最大公约数。

代码如下:

Memory: 180K		Time: 204MS
Language: C++		Result: Accepted

#include<iostream>  
#include<cstdio>  
#include<cmath>  
using namespace std;  
  
const int N=1000;  
const int M=10000;  
  
int n;  
int t[N],r[N];  
  
int c[M];  
  
int gcd(int a,int b)  
{  
    if(!b) return a;  
    return gcd(b,a % b);  
}  
  
void run()  
{  
    int i,j;  
  
    for(i=0;i<n;i++) scanf("%d",&t[i]);  
  
    r[0]=1;  
    for(i=1;i<N;i++) r[i]=0;  
  
    int a,b,g,d,k;  
  
    d=0;  
    for(i=1;i<n;i++) if(t[i]!=t[0])  
    {  
        b = t[i] * t[0];  
        a = abs(t[i] - t[0])<<1;  
        g = gcd(a,b);  
  
        a/=g;  
        b/=g;  
        d=gcd(a,d);  
  
        //分解素因子  
        for(j = 2; b > 1; j++ ) if(b % j == 0)  
        {  
            k=0;  
            while(b % j == 0)  
            {  
                b /= j;  
                k++;  
            }  
            if(k > c[j]) c[j] = k;  
        }  
    }  
  
    //lrj结论:  lcm(a,b)=p1^max(a1,b1)*p2^max(a2,b2)……pn^max(an,bn)  
    //here:     预先计算出 所有bi的素因子个数 max 存放在 c[i] 数组中  
    //大整数乘法 r=∏(i^c[i]) {c[i]!=0}  
    int tmp;  
    for(i = 0; i < M; i++)  
    {  
        for(j=0; j<c[i]; j++)  
        {  
            tmp = 0;  
            for(k = 0; k < N; k++)  
            {  
                r[k] = r[k]*i+tmp;  
                tmp = r[k] / 10000;  
                r[k] %= 10000;  
            }  
        }  
    }  
  
    //ans : (r[i] / d)  
    i=999;  
    while(i && r[i] == 0) i--;  
  
    printf("%d",r[i]);  
    for(--i;i>=0;--i) printf("%04d",r[i]);  
  
    printf(" %d\n",d);    
}  
  
int main()  
{  
    while(scanf("%d",&n)!=EOF) run();  
    return 0;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值