[藍橋杯] 最大比例


[藍橋杯] 最大比例

峰值內存消耗 < 256M  CPU消耗  < 3000ms

【題目描述 - Problem Description】

X星球的某個大獎賽設了M級獎勵。每個級別的獎金是一個正整數。

 

並且,相鄰的兩個級別間的比例是個固定值。

也就是說:所有級別的獎金數構成了一個等比數列。

比如: 16,24,36,54

其等比值為:3/2

 

現在,我們隨機調查了一些獲獎者的獎金數。

請你據此推算可能的最大的等比值。

 

輸入格式:

第一行為數字N(N<=100),表示接下的一行包含N個正整數

第二行N個正整數Xi(Xi<1 000 000 000 000),用空格分開。每個整數表示調查到的某人的獎金數額

 

要求輸出:

一個形如A/B的分數,要求A、B互質。表示可能的最大比例系數

 

測試數據保證了輸入格式正確,並且最大比例是存在的。

 

輸入 3
1250 200 32
4
3125 32 32 200
3
549755813888 524288 2
輸出 25/4 5/2 4/1

 

 

 

 

【題解】

  等比數列求公比,Xi < 10^12

  先對各項排序,兩兩相除並約分,只要保證每次計算結果大於1,最后剩下的就是最大公比。

  N=100,O(N*N)還算可以接受。

  需要注意去重,以及公比為1的情況。

 

  數據范圍10^12看起來誠惶誠恐,直接欽定long long可能會有人擔心出現10^24的情況,(因為強迫症)於是就寫了簡單的證明……

 

設等比數列通項:

由於都是整數項,遇到分數形式的公比必然為整除。
因此z, m < 10^12


在第一輪除法中,首項被消除,只留下公比的任意次冪,小於1則分子分母互換。
運算中由於GCD的存在:

因此在第一輪的計算峰值不會超過10^12次方


在第2~n輪的計算中,由於去除了不確定的首項,可以把通項轉化如下(其實一開始去掉首項也一樣):

  兩兩相除時:

很遺憾,計算峰值還是無法超過10^12

 

【代碼 C++】

 1 #include <cstdio>
 2 #include <algorithm>
 3 struct fs {
 4     __int64 fz, fm;
 5     bool operator == (const fs &B)const {
 6         if (B.fz != fz || B.fm != fm) return 0;
 7         return 1;
 8     }
 9 }data[105];
10 __int64 rd[105];
11 __int64 GCD(__int64 a, __int64 b) {
12     __int64 c;
13     while (c = a%b) a = b, b = c;
14     return b;
15 }
16 fs slv(fs a, fs b) {
17     if (a == b) return a;
18     __int64 gcd;
19     gcd = GCD(a.fz, b.fz);
20     a.fz /= gcd; b.fz /= gcd;
21     gcd = GCD(a.fm, b.fm);
22     a.fm /= gcd; b.fm /= gcd;
23     a.fz *= b.fm;
24     b.fz *= a.fm;
25     if (a.fz > b.fz) a.fm = b.fz;
26     else a.fm = a.fz, a.fz = b.fz;
27     return a;
28 }
29 int main() {
30     int i, j, n;
31     scanf("%d", &n);
32     for (i = 0; i < n; ++i) scanf("%I64d", rd + i), data[i].fm = 1;
33     std::sort(rd, rd + n);
34     for (i = j = 0; i < n; ++i) if (rd[i] != rd[i + 1]) data[j++].fz = rd[i];
35     for (n = j - 1; n; --n) {
36         for (i = 0; i < n; ++i) data[i] = slv(data[i], data[i + 1]);
37     }
38     if (j == 1) puts("1/1");
39     else printf("%I64d/%I64d", data[0].fz, data[0].fm);
40     return 0;
41 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM