[Acwing蓝桥杯数学知识] 1223. 最大比例
题目大概意思就是 取等比数列中任意多个数 求他们所能组成的最大等比值
有点类似与等差数列 数据范围很大
思路:
类似等差数列 先求出所有的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!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人