POJ 3103 Astronomy

38 篇文章 0 订阅
22 篇文章 0 订阅

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
这里写图片描述
题目大意
已知每个星体的运行周期,问最少经过多长时间所有的星体能够处于同一条直径上。

解题思路

这道题好像可以是一道单纯的数学题~
1、以第一个星体为参照点,假设其周期为T0,其余星体的周期为Ti,则两个星体的角速度差值为 ω=2πT02πTi ,然后以角速度经过 π 为基本单位计算时间差值,则 t=T0Ti2(TiT0) ,则可通过计算之后每个星体相对于第一个星体的 ∆t,它们的最小公倍数即为所求时间。
2、求一系列分数的lcm=分子的lcm/分母的gcd。
3、涉及到大数乘法的处理,因为这里星体个数范围为1000,星体周期为10000,所以开辟1000位数组对数据压4位来存储结果。

代码实现

#include <iostream>
#include<cstdio>
#include<stdlib.h>
#include<cstring>
#include<cmath>
using namespace std;
#define N 1000
#define M 10000
int r[N];
int a,b,c,d;
int countt[M];
int T0,T1;
//求gcd
int gcd(int a,int b)
{
    if(!b) return a;
    else return gcd(b,a%b);
}
//素因子分解
void getfac(int x)
{
    int num;
    for(int j=2; x>1; j++)
    {
        if(x%j==0)
        {
            num=0;
            while(x%j==0)
            {
                num++;
                x/=j;
            }
        if(num>countt[j]) countt[j]=num;    //countt[]记录每个因子的个数
        }
    }
}
void getup()
{
    int temp;
    for(int i=0; i<M; i++)                //M代表因子的范围,因为1<=ti<=10000,则i最大值为9997
    {
        for(int j=0; j<countt[i]; j++)    //j遍历因子个数
        {
            temp=0;
            for(int k=0; k<N; k++)         //N代表位数的极限,示例:9997 9995 9993
            {
                r[k]=r[k]*i+temp;
                temp=r[k]/10000;
                r[k]%=10000;
            }
        }
    }
}
int main()
{
    int T;
    while(~scanf("%d",&T))
    {
        memset(countt,0,sizeof(countt));
        d=0;
        scanf("%d",&T0);
        T--;
        while(T--)
        {
            scanf("%d",&T1);
            if(T1!=T0)
            {
                a=T0*T1;
                b=2*abs(T0-T1);
                c=gcd(a,b);
                a=a/c;
                b=b/c;
                d=gcd(b,d);
                getfac(a);
            }
        }
        memset(r,0,sizeof(r));
        r[0]=1;
        getup();
        int 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);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值