题目:
X星球的某个大奖赛设了M级奖励。每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。比如:
16,24,36,54
其等比值为:3/2
现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。
输入格式
第一行为数字N,表示接下的一行包含N个正整数
第二行N个正整数Xi(Xi<1 000 000 000 000),用空格分开。每个整数表示调查到的某人的奖金数额
要求输出:
一个形如A/B的分数,要求A、B互质。表示可能的最大比例系数
测试数据保证了输入格式正确,并且最大比例是存在的。
例如,输入:
3
1250 200 32
程序应该输出:
25/4
再例如,输入:
4
3125 32 32 200
程序应该输出:
5/2
再例如,输入:
3
549755813888 524288 2
程序应该输出:
4/1
分析:
1. 将N个正整数从小到大排列,去重
2. 根据等比数列的性质,两两之间进行比值,再将比值的分子分母约到最简分别存储到分子分母表
3. 分别求出分子表和分母表的最大公共次方,即是答案
这里新学到了一种算法,当知道两个数 x,y。 x=p^i y=p^j 那么我们怎么求这个p呢?
long long qgcd(long long a,long long b){
if(a==b)return a;
else{
return qgcd(min(b/a,a),max(b/a,a));
}
}
代码:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long L;
L gcd(L m,L n){
if(n==0) return m;
return gcd(n,m%n);
}
L ggcd(L a,L b){
if(a==b) return a;
return ggcd(min(b/a,a),max(b/a,a));
}
int main(){
int N;
cin >> N;
L arr[N];
for(int i=0;i<N;i++){
cin >> arr[i];
}
sort(arr,arr+N);
vector<L> a,b;
for(int i=0;i<N-1;i++){//分子分母约分
if(arr[i]!=arr[i+1]){
L k = gcd(arr[i],arr[i+1]);
a.push_back(arr[i+1]/k);
b.push_back(arr[i]/k);
}
}
L m=a[0],n=b[0];
for(int i=1;i<a.size();i++){//各自求分子和分母的最大公共次方
m = ggcd(m,a[i]);
n = ggcd(n,b[i]);
}
cout << m << "/" << n;
return 0;
}
检测过后只得了75分,我也不知道错在哪?^^日后还会回来复习,继续完善