2015年第七屆藍橋杯C/C++B組第十題

最大比例

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

那麼最後剩下的就是滿足的情況了。 就是最大的公比。

總結一下就是:

qx&gt;qyq^x &gt; q^yqy/qxq^y / q^x

qx&lt;qyq^x &lt; q^yqx/qyq^x / q^y

qx==qyq^x == q^yqxq^x 就是公比

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章