AcWing 1223. 最大比例

AcWing 1223. 最大比例

题目

X星球的某个大奖赛设了 M 级奖励。

每个级别的奖金是一个正整数。

并且,相邻的两个级别间的比例是个固定值。

也就是说:所有级别的奖金数构成了一个等比数列。

比如:16,24,36,54,其等比值为:3/2。

现在,我们随机调查了一些获奖者的奖金数。

请你据此推算可能的最大的等比值。

输入格式
第一行为数字 N ,表示接下的一行包含 N 个正整数。

第二行 N 个正整数 Xi,用空格分开,每个整数表示调查到的某人的奖金数额。

输出格式
一个形如 A/B 的分数,要求 A、B 互质,表示可能的最大比例系数。

数据范围
0 < N < 100 0<N<100 0<N<100
0 < X i < 1 0 12 0<X_i<10^{12} 0<Xi<1012
数据保证一定有解。

思路

对于 a 1... n a_{1...n} a1...n排序去重得到 b 1.. m b_{1..m} b1..m。将它们两两之间的比值求出,得到 r 2.. m r_{2..m} r2..m
r i = ( p q ) x i r_i = (\frac{p}{q})^{x_i} ri=(qp)xi
若我们已知p,q,x,那么,要求的最大值必然是 ( p q ) k (\frac{p}{q})^k (qp)k,其中 k = g c d ( x 2... m ) k=gcd(x_{2...m}) k=gcd(x2...m)。而如今我们并不知道它们分别为多少,仅知道它们的幂。
不妨设F(a,b)就是a,b之间的最佳比例,我们对于p,q分别计算,这里仅讨论p。
F ( a , b ) = F ( p x , p y )      ( y > x ) = p g c d ( x , y ) = p g c d ( x , y − x )     ( 这 里 采 用 辗 转 相 减 , 由 于 在 指 数 部 分 , 使 用 除 法 要 开 方 , 并 不 适 用 于 我 们 的 整 数 计 算 ) = F ( p x , p y − x ) \begin{aligned} F(a,b) &=F(p^x,p^y)~~~~(y>x)\\ &=p^{gcd(x,y)}\\ &=p^{gcd(x,y-x)}~~~(这里采用辗转相减,由于在指数部分,使用除法要开方,并不适用于我们的整数计算)\\ &=F(p^x,p^{y-x}) \end{aligned} F(a,b)=F(px,py)    (y>x)=pgcd(x,y)=pgcd(x,yx)   (使)=F(px,pyx)
从而可以得到最佳比例。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 105;
#define int long long
int a[N],n;
int up[N],down[N];

int gcd(int a,int b)
{
    return b == 0 ? a : gcd(b,a%b);
}

int pgcd(int a,int b)
{
    if(a > b)
        swap(a,b);
    if(a == b)
        return a;
    return pgcd(a,b/a);
}

signed main()
{
    cin>>n;
    for (int i = 1; i <= n; i ++ )
        cin>>a[i];
    sort(a+1,a+n+1);
    int m = unique(a+1,a+n+1) - a - 1;
    for (int i = 2; i <= m ; i ++)
    {
        int d = gcd(a[i],a[1]);
        up[i] = a[i] / d;
        down[i] = a[1] / d;
    }
    int u = up[2] , dw = down[2];
    for (int i = 2 ; i <= m ; i ++)
    {
        u = pgcd(u,up[i]);
        dw = pgcd(dw,down[i]);
    }
    cout<<u<<"/"<<dw;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值