b537. 分數運算-1

解法一

🔹 反推

首先 一定要記得約分
__gcd() 計算最大公因數作為分母約分

答案會爆 int 需要用 long long

函數 f(k)

根據題目敘述
函數 f(k) 返回兩個值 a, b
a 是分子,b 是分母 (ab\frac{a}{b})

pair<int, int> f(int k){
    if(k == 1) return {1, 1};
    
    if(k & 1){
        auto fk = f(k-1);
        return {fk.second, fk.first};
    }
    else{
        auto fk = f(k/2);
        return {fk.first+fk.second, fk.second};
    }
}

回推 g(a, b)

實現 g(a, b) 找回 k

從 f(k) 中觀察到返回值的特性

最終回推得到

✅ 完整代碼

評分結果(參考) : AC (2ms, 356KB)

#include<bits/stdc++.h>
#define int long long
using namespace std;

int g(int a, int b){
    if(a == 1 && b == 1) return 1;

    if(a > b){
        return g(a-b, b) * 2;
    } 
    else{
        return g(b, a) + 1;
    }
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int a, b;
    while(cin >> a >> b){
        int c = __gcd(a, b);
        cout << g(a/c, b/c) << "\n";
    }
    
    return 0;
}

解法二、解法一優化版

🔹 合併處理 a > b

a>ba > b
aa 可能需要減多次 bb 才能使得 a<ba < b (或 a=ba = b),而進入另一種狀態

g(99, 2)
= g(99-2, 2) *2
= g(97-2, 2) *2 *2
= g(95-2, 2) *2 *2 *2
= …

可以一起處理 a>ba > b 的狀況
計算重複處理的次數 q,以及處理後剩餘的數 r
q = a/b, r = a%b,改返回為 g(r, b) * pow(2, q)
這樣便一次處理完了 a>ba > b 的狀況

再用右移 << 優化 : g(r, b)<<q

另外注意 b = 1 的情況 (a 會被整除,導致 r = 0)

✅ 完整代碼

評分結果(參考) : AC (2ms, 316KB)

#include<bits/stdc++.h>
#define int long long
using namespace std;

int g(int a, int b){
    if(a==1 && b==1) return 1;

    if(a > b){
        int q = a/b;
        int r = a%b;
        
        if(b == 1) return g(r+1, b)<<(q-1);
        else return g(r, b)<<q;
    } 
    else{
        return g(b, a)+1;
    }
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int a, b;
    while(cin >> a >> b){
        int c = __gcd(a, b);
        cout << g(a/c, b/c) << "\n";
    }
    
    return 0;
}