AcWing 1223. 最大比例

原题链接

思路

首先肯定和等差数列类似,先把所输入的项排序去重,然后两两相邻项进行整除,可以得到许多的商(全部都是最大公比的若干倍)
然后也和等差数列类似,要想办法求出在乘方后能够得到所有得到的商的最大数,等差数列将所有的差求gcd就行,那么等比数列却不行,怎么办?
假设所求最大公比是\(p/q\), 注意到所有得到的商都是 \(p^x / q^x\), 因此,只需要把它们的指数求gcd即可。
但是\(p/q\)是未知的,因此也无从确定所得商的指数,怎么办?巧妙就在这里!
又注意到指数不会太大,而且指数的减法可以表示为原来的数的除法,因此用gcd_sub(更相减损术)即可解决!

代码

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

const int N = 110;
typedef long long ll;
ll x[N], a[N], b[N];

ll gcd(ll a, ll b)
{
    return b ? gcd(b, a % b) : a;
}

ll gcd_sub(ll a, ll b)      //更相减损术
{
    if(a < b) swap(a, b);
    if(b == 1) return a;
    return gcd_sub(b, a / b);
}

int main()
{
    int n;
    cin >> n;
    for(int i = 0 ; i < n ; i ++)   cin >> x[i];
    sort(x, x + n);
    int len = unique(x, x + n) - x;      //排序并去除重复的项
    for(int i = 1 ; i < len ; i ++)      //求出相邻两项的商 其中a代表分子,b代表分母
    {
        ll d = gcd(x[i], x[i - 1]);
        a[i - 1] = x[i] / d;
        b[i - 1] = x[i - 1] / d;
    }
    
    ll up = a[0], down = b[0];          //对所有的商的质数求最大公约数
    for(int i = 1 ; i < len - 1 ; i ++)
    {
        up = gcd_sub(up, a[i]);
        down = gcd_sub(down, b[i]);
    }
    cout << up << "/" << down << endl;
    return 0;
}
posted @ 2021-03-31 00:39  beatlesss  阅读(58)  评论(0编辑  收藏  举报