题目
X星球的某个大奖赛设了 M M M 级奖励。
每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。
比如: 16 , 24 , 36 , 54 16,24,36,54 16,24,36,54,其等比值为: 3 / 2 3/2 3/2。
现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。
输入格式
第一行为数字 N N N ,表示接下的一行包含 N N N 个正整数。
第二行 N N N 个正整数 X i X_i Xi,用空格分开,每个整数表示调查到的某人的奖金数额。
输出格式
一个形如 A / B A/B A/B 的分数,要求 A 、 B A、B A、B 互质,表示可能的最大比例系数。
数据范围
0
<
N
<
100
0 < N < 100
0<N<100
0
<
X
i
<
1
0
12
0 < X_i < 10^{12}
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
思路:
- 取到相邻两个数的比例,放入set()中;
- 取得分子,分母的最大公约数(如 样例2中 25/4 , 125/8 得到 a=25 ,b = 4)
- 因为答案肯定是原比例的约数,又肯定比2中要小(分子<分子;分母<分母),所以答案藏在其中,枚举约数,又因为答案的分子^n /分母 ^n 构成了 1 中得到的比例,所以我们求2 中得到a,b 的满足pow(minia,n) ==a的最小约数。(比如说a = 8 ,那么我们得到2,因为2^ 3 ==8;a = 12,我们得到12就可以了,因为只有12^1 ==12满足条件)
(附上自己的丑代码)
import math
n = int(input())
h = list(map(int,input().split()))
k = set()
def gcd(a,b):
if b==0:return a
return gcd(b,a%b)
h.sort()
for i in range(1,n):
t = gcd(h[i],h[i-1])
a = h[i]//(t)
b = h[i-1]//t
if a == b :continue
k.add((a,b))
#print(k)
k = list(k)
a , b =k[0][0],k[0][1]
for x,y in k[1:]:
a = gcd(a,x)
b = gcd(b,y)
#print(a,b)
def findMiniPrime(n):
if n ==1:return 1
i = 2; t =int(n**0.5);nn = n;f=False
while i<=t and n!=1:
if (nn%i == 0 and math.log(nn)/math.log(i)-int(math.log(nn)/math.log(i)) <1e-5):
f=True
break
i+=1
if f:return i
return nn
a = findMiniPrime(a)
b = findMiniPrime(b)
minia = a
minib = b
cnt = 1
#print(math.log(k[0][0])/math.log(a)-math.log(k[0][0])//math.log(a) == 0)
def judge(x,a):
if a == 1:return False
return (math.log(x)/math.log(a)-int(math.log(x)/math.log(a)))<1e-5
f = [True,True]
while True:
for x in k:
#print(x,a,math.log(x[0])/math.log(a),int(math.log(x[0])/math.log(a)),judge(x[0],a))
if (not judge(x[0],a)) or a>x[0] :
f[0] = False
break
if f[0]:
a*=minia
else:break
while True:
for x in k:
if (not judge(x[1],b)) or b>x[1] :
f[1] = False
break
if f[1]:
b*=minib
else:break
#print(a,' ',b)
print(a//minia,"/", b//minib,sep = '')
#print(k,minia,minib)