最大比例
题目描述:
X星球的某个大奖赛设了M级奖励。每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。比如:
16,24,36,54
其等比值为:3/2
现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。
输入格式:
第一行为数字 N (0<N<100),表示接下的一行包含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
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 3000ms
题目分析:
题目告诉我们输入的数字一定是等比关系, 那么把所有的奖金按从小到大排序, 重复的剔除。 既然是等比关系, 那么一定有公比q(也就是要求的答案)。后面的每一个奖金都比上第0项的值一定是 q x q^x qx , x未知。既然这样我们不妨假设第0项就是公比。如果后面的每一个比都是它的幂, 则他就是最大的公比。反之我们求同时满足这俩的公比。 也就是说。 如果答案是q, 第0项是 q x q^x qx 第i个比是 q y q^y qy , 那么 q y q^y qy 一直除以 q x q^x qx 就会得到 y < x 或 x == y。 如果x == y,那我继续找下一个。 知道所有都符合, q就是最大公比。 如果x > y, 那么就 反过来再除, 知道找到x == y为止。 一定存在这种情况, 因为最后一定有一个公比q, 当x == 1的时候一定成立。
那么最后剩下的就是满足的情况了。 就是最大的公比。
总结一下就是:
q x > q y q^x > q^y qx>qy 则 q y / q x q^y / q^x qy/qx
q x < q y q^x < q^y qx<qy 则 q x / q y q^x / q^y qx/qy
q x = = q y q^x == q^y qx==qy 则 q x q^x qx 就是公比
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long
ll X[105];
ll gcd(ll a, ll b)
{
if(a % b == 0) return b;
else return gcd(b, a%b);
}
struct Fract
{
ll a, b;
}F[105];
bool cheek(Fract &x, Fract &y)
{
bool ok = true;
while(x.a != y.a)
{
while(x.a < y.a)
{
y.a /= x.a;
y.b /= x.b;
}
while(x.a > y.a)
{
ok = false;
x.a /= y.a;
x.b /= y.b;
}
}
return ok;
}
int main()
{
int n;
scanf("%d", &n);
for(int i=0; i<n; ++i)
scanf("%lld", &X[i]);
int t = 0;
sort(X, X+n);
for(int i=1; i<n; ++i)
{
if(X[i] == X[i-1]) continue;
else //化成最简分数
{
ll c = gcd(X[i], X[0]);
F[t++] = (Fract){X[i]/c, X[0]/c};
}
}
bool ok = false;
while(!ok)
{
ok = true;
for(int i=1; i<t; ++i)
if(!cheek(F[0], F[i])) ok = false;
}
printf("%lld/%lld\n", F[0].a, F[0].b);
return 0;
}