题目如下:
题解 or 思路:
假设题中所给的数据为
b
1
,
b
2
,
b
3
,
⋅
⋅
⋅
,
b
n
b_1,b_2,b_3,⋅⋅⋅,b_n
b1,b2,b3,⋅⋅⋅,bn,分别用第一项之后的项除以第一项,得到:
b
2
b
1
,
b
3
b
1
,
⋅
⋅
⋅
,
b
n
b
1
\frac{b2}{b1},\frac{b3}{b1},⋅⋅⋅,\frac{bn}{b1}
b1b2,b1b3,⋅⋅⋅,b1bn,由于给出的数都是等比数列中的数,所以(
p
q
)
α
1
,
(
p
q
)
α
2
,
⋅
⋅
⋅
,
(
p
q
)
α
n
−
1
\frac{p}{q})^{α_1},(\frac{p}{q})^{α_2},···,(\frac{p}{q})^{α_{n-1}}
qp)α1,(qp)α2,⋅⋅⋅,(qp)αn−1。如果
(
p
q
)
k
(\frac{p}{q})^{k}
(qp)k为最大的公比,那么
k
k
k 应该为
α
1
,
α
2
,
⋅
⋅
⋅
,
α
n
−
1
α_1,α_2,⋅⋅⋅,α_{n−1}
α1,α2,⋅⋅⋅,αn−1 的最大公约数。
需要满足的条件:
- 保证 p p p, q q q 互质
- 保证
p
p
p,
q
q
q 不能再分成幂次的形式
这样才能保证求得的k为准确的数。
辗转相减法应用:
辗转相除法可以用来求若干个形如 ( p q ) r i (\frac{p}{q})^{r_i} (qp)ri 的最大公约数
证明:
g c d ( p x , p y ) = p g c d ( x , y ) = p g c d ( y , x − y ) = g c d ( p y , p ( x − y ) ) = g c d ( p y , p x p y ) gcd(p^x, p^y) = p^{gcd(x, y)} = p^{gcd(y, x - y)} = gcd(p^y,p^{(x - y)}) = gcd(p^y, \frac{p^x}{p^y}) gcd(px,py)=pgcd(x,y)=pgcd(y,x−y)=gcd(py,p(x−y))=gcd(py,pypx)
注每一次递归都需要保证 x > y x > y x>y
时间复杂度: O ( n ) O(n) O(n)
AC 代码:
注:
a
a
a 数组记录分子,
b
b
b 数组记录分母
#define int long long
const int N = 100009;
int a[109], b[109], s[109];
int n;
int gcd_sub(int x, int y)
{
if (x < y)
swap(x, y);
if (y == 1)
return x;
return gcd_sub(y, x / y);
}
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> s[i];
sort(s + 1, s + 1 + n);
int cnt = 0;
for (int i = 2; i <= n; i++)
if (s[i] != s[i - 1])
{
int d = __gcd(s[i], s[1]);
a[++cnt] = s[i] / d;
b[cnt] = s[1] / d;
}
int x = a[1], y = b[1];
for (int i = 2; i <= cnt; i++)
{
x = __gcd(x, a[i]);
y = __gcd(y, b[i]);
}
cout << x << '/' << y << '\n';
}
signed main()
{
buff;
solve();
}