1223. 最大比例
考察要点:数论 最大公约数 辗转相减法
题目要求
X星球的某个大奖赛设了 M 级奖励。
每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。
比如:16,24,36,54,其等比值为:3/2。
现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。
输入格式
第一行为数字 N ,表示接下的一行包含 N 个正整数。
第二行 N 个正整数 Xi,用空格分开,每个整数表示调查到的某人的奖金数额。
输出格式
一个形如 A/B 的分数,要求 A、B 互质,表示可能的最大比例系数。
数据范围
0<N<100
0<Xi<1012
数据保证一定有解。
输入样例1:
3
1250 200 32
输出样例1:
25/4
输入样例2:
4
3125 32 32 200
输出样例2:
5/2
输入样例3:
3
549755813888 524288 2
输出样例3:
4/1
题目地址:https://www.acwing.com/problem/content/1225/
解析:
代码思路 :对输入的数据进行排序、去重,然后求出等比数列对于a0的比值的分子分母。然后分别求出分子分母的最大公约数
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
int n;
const int N = 110;
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; //指数相同所以相除为1
return gcd_sub(b, a / b); //求的是指数的最大公约数 所以使用的是除法,让指数先减
}
int main()
{
cin >> n;
for(int i = 0; i < n; i ++) cin >> x[i];
sort(x, x + n); //从小到大排序
int cnt = 0;
for(int i = 1; i < n; i ++)
{
if(x[i] != x[i - 1]) //去重
{
LL d = gcd(x[i], x[0]); //求出x[i] 和 x[0]的 最大公约数
a[cnt] = x[i] / d; //得到x[i]/x[0]的分子
b[cnt] = x[0] / d; //得到x[i]/x[0]的分母
cout << a[cnt] << "/" << b[cnt] << endl;
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;
}
本题:1223. 最大比例
代码参考:视频讲解