X星球的某个大奖赛设了 M 级奖励。
每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。
比如:16,24,36,54,其等比值为:3/2。
现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。
输入格式
第一行为数字 N ,表示接下的一行包含 N 个正整数。
第二行 N 个正整数 Xi,用空格分开,每个整数表示调查到的某人的奖金数额。
输出格式
一个形如 A/B 的分数,要求 A、B 互质,表示可能的最大比例系数。
数据范围
0<N<100
0<Xi<10^12
数据保证一定有解。
输入样例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
题解
设给定数列从小到大排序后为 b0 b1 b2 b3 bn-1,将每个数都除以b0后得
b1/b0 、b2/b0 、b3/b0 … bn-1/b0
=> (p/q)x1 、(p/q)x2 、(p/q)x3… (p/q)xn-1
求(p/q)x1 、(p/q)x2 、(p/q)x3… (p/q)xn-1的最大公约数 (p/q)k 就是答案,那么就是求x1、x2、x3 … xn-1 指数的最大公约数,因为这个题 p/q 不是整数,是分数,因此我们用辗转相除法无法做,只能用对指数的更相减损术
分母分子分开求,因为指数是一样的,px1/px2=p(x1-x2) 设函数 f (a,b) 可求得两个数最大公约数,则我们 f(a,b) = f(b,a/b) 因为 a/b 相当于指数做减法,
循环相除,当 x1=x2时, 相除为1,返回a,就是(px1,px2)的最大公约数
这里用到了更相减损术,指数相减等于两个数相除
另外一个比较易懂的题解 https://www.acwing.com/solution/content/22658/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 105;
LL a[N],up[N],down[N];
int cnt;
LL gcd(LL a,LL b)
{
if(b==0)return a;
else return gcd(b,a%b);
}
LL gcd_sub(LL a,LL b)
{
if(a<b) swap(a,b);
if(b==1) return a;
else return gcd_sub(b,a/b);
}
int main()
{
int n;
cin>>n;
for(int i=0; i<n; ++i){
cin>>a[i];
}
sort(a,a+n);
for(int i=1; i<n; ++i){
if(a[i]!=a[i-1]){
LL d = gcd(a[i],a[0]);
up[cnt] = a[i];
down[cnt] = a[0];
cnt++;
}
}
LL ans_up=up[0],ans_down=down[0];
for(int i=0; i<cnt; ++i){
ans_up = gcd_sub(ans_up,up[i]);
ans_down = gcd_sub(ans_down,down[i]);
}
cout<<ans_up<<'/'<<ans_down<<endl;
return 0;
}