[Acwing蓝桥杯数学知识] 1223. 最大比例

题目链接:1223. 最大比例 - AcWing题库

题目大概意思就是 取等比数列中任意多个数 求他们所能组成的最大等比值

有点类似与等差数列 数据范围很大

思路:

类似等差数列 先求出所有的q的倍数 q^1 q^2...q^k

然后然后求这些倍数的最大公约数

这个题有个难点是 当求含由分数指数的最大公约数怎么求?

分数指数可以分子和分母分别看 分别求分子和分母的最大公约数

那么指数怎么班 如果是指数用辗转相除法那么数会非常大

幂的最大公约数怎么求?

那么就用辗转相减法(只用了原理,模板中没有减号)

真实名字叫更相减损术

/*更相减损术:第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。

第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。
则第一步中约掉的若干个2的积与第二步中等数的乘积就是所求的最大公约数。*/

辗转相除法的模板:

//辗转相减法
LL gcd_sub(LL a,LL b)
{
    if(a<b)swap(a,b);
    if(b==1)return a;
    return gcd_sub(b,a/b);
}

那么整个题的代码:

复制代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=110;
int n;
LL x[N],a[N],b[N];

LL gcd(LL a,LL b)
{
    if(!b)return a;
    return gcd(b,a%b);
}

//辗转相减法
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()
{
    cin>>n;
    
    for(int i=0;i<n;i++)scanf("%lld",&x[i]);
    
    sort(x,x+n);
    int cnt=0;
    
    for(int i=1;i<n;i++)
    {
        if(x[i]!=x[0])
        {
            LL d=gcd(x[i],x[0]);
            a[cnt]=x[i]/d;
            b[cnt]=x[0]/d;
            cnt++;
        }
    }
    
    LL up=a[0],down=b[0];
    for(int i=1;i<cnt;i++)
    {
        up=gcd_sub(up,a[i]);
        down=gcd_sub(down,b[i]);
    }
    
    cout<<up<<"/"<<down<<endl;
    
    return 0;
}
复制代码

end!!!

 

posted @   秦末  阅读(187)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
1 博文导航目录
点击右上角即可分享
微信分享提示