Date:2022.04.06
题意描述:
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
思路:随机调查若干个,且等比可能是分数,因此我们将所有项表示为:
a、a∗qx1、......、a∗qxka、a*q^{x_1}、......、a*q^{x_k}a、a∗qx1、......、a∗qxk。
之后将所有项第一项\frac{所有项}{第一项}第一项所有项约分后,所有项都会转化为等比的若干次幂,形势如下:(pq)k1、(pq)k2、......、(pq)km(\frac{p}{q})^{k_1}、(\frac{p}{q})^{k_2}、......、(\frac{p}{q})^{k_m}(qp)k1、(qp)k2、......、(qp)km
由此不难发现,等比即找k1、k2、......、kmk_1、k_2、......、k_mk1、k2、......、km的gcdgcdgcd即可。
但我们要注意,我们约分后并不知道pq\frac{p}{q}qp的值,因此无法直接对所有幂求gcdgcdgcd,但我们可以预处理出分子和分母,分别求所有分母qk1、qk2、......、qkmq^{k_1}、q^{k_2}、......、q^{k_m}qk1、qk2、......、qkm和分子的gcdgcdgcd再相除。但由于是对幂次求gcdgcdgcd,无法直接辗转相除,因为次幂取模不好处理。因此考虑求gcdgcdgcd的新方法------辗转相减(也就是更相减损术)。
我们要构造的函数无非是:f(px,py)=pgcd(x,y)f(p^x,p^y)=p^{gcd(x,y)}f(px,py)=pgcd(x,y),因此我们反推对次幂更相减损后得到p(x,y)==p(y,y−x),转换为函数形式即为:p^{(x,y)}==p^{(y,y-x)},转换为函数形式即为:p(x,y)==p(y,y−x),转换为函数形式即为:f(py,pypx)f(p^y,\frac{p^y}{p^x})f(py,pxpy),一路递归,直到后一项次幂为1弹出。
此外,注意更相减损时要用大的减小的,因此我们考虑两个次幂大小,若某一步前面的次幂<后面的次幂,交换位置。而且,题中重复元素要去掉,并不算入这些过程中。
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
typedef long long LL;
LL n,m,k,t,a[N],b[N],x[N],cnt;
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=1;i<=n;i++) cin>>x[i];
sort(x+1,x+1+n);
LL idx=unique(x+1,x+1+n)-x-1;
for(int i=2;i<=n;i++)
{
LL d=gcd(x[i],x[1]);
a[++cnt]=x[i]/d;
b[cnt]=x[1]/d;
}
LL up=a[1],down=b[1];
for(int i=2;i<idx;i++)
{
up=gcd_sub(up,a[i]);
down=gcd_sub(down,b[i]);
}
cout<<up<<'/'<<down;
return 0;
}
本文探讨了如何通过调查X星球大奖赛的随机奖金数据,推算出可能的最大等比值。利用等比数列性质,通过约分和辗转相减算法求解 gcd,揭示奖金数额间的比例规律。
1991

被折叠的 条评论
为什么被折叠?



