最大比例
題目描述:
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項的值一定是 , x未知。既然這樣我們不妨假設第0項就是公比。如果後面的每一個比都是它的冪, 則他就是最大的公比。反之我們求同時滿足這倆的公比。 也就是說。 如果答案是q, 第0項是 第i個比是 , 那麼 一直除以 就會得到 y < x 或 x == y。 如果x == y,那我繼續找下一個。 知道所有都符合, q就是最大公比。 如果x > y, 那麼就 反過來再除, 知道找到x == y爲止。 一定存在這種情況, 因爲最後一定有一個公比q, 當x == 1的時候一定成立。
那麼最後剩下的就是滿足的情況了。 就是最大的公比。
總結一下就是:
則
則
則 就是公比
#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;
}