1. 程式人生 > 其它 >LuoguP7679 [COCI2008-2009#5] JABUKA 題解

LuoguP7679 [COCI2008-2009#5] JABUKA 題解

LuoguP7679 [COCI2008-2009#5] JABUKA 題解

Content

Mirko 擁有 \(R\) 個紅蘋果和 \(G\) 個綠蘋果,他想把他分給若干個朋友,使得所有朋友分得的紅蘋果個數和綠蘋果個數都一樣。現給定 \(R,G\),請你幫助 Mirko 找到所有的分配蘋果的方案。可以證明一定存在分配蘋果的方案。

資料範圍:\(1\leqslant R,G\leqslant 10^9\)

Solution

供題的時候也沒有想到會有複雜度 \(\mathcal O(\gcd\{R,G\})\) 的複雜度過去……於是隨手造了個數據把錯解卡了,順便來水水題解。

我們發現,朋友的個數必然是 \(R,G\) 的公因數,所以我們不妨先求出 \(\gcd\{R,G\}\)

,然後在修改了資料之後,直接列舉到 \(\gcd\{R,G\}\) 肯定是不可行的了。那怎麼辦呢?我們不妨想想,如果 \(x\) 是一個數 \(n\) 的因子,那麼 \(\dfrac{n}{x}\) 肯定也是這個數的因子。所以我們不妨以 \(\left\lfloor\sqrt{\gcd\{R,G\}}\right\rfloor\) 為上界列舉朋友個數,一旦找到了一個因子 \(i\) 就把朋友數分別為 \(i\)\(\dfrac{\gcd\{R,G\}}{i}\) 的方案全加入答案中,這樣既可以保證面面俱到,又可以保證時間不會超限。

又由於這道題目要求我們要按照朋友個數升序排列,於是我們就可以開一個 vector,把答案計入到 vector 之後直接按照朋友個數升序排序輸出就好了。具體實現見程式碼。

Code

struct node {
    int p, ri, gi;
    bool operator < (const node& t) const {return p < t.p;}
};
vector<node> ans;

int main() {
    int r = Rint, g = Rint, n = __gcd(r, g);
    F(int, i, 1, (int)sqrt(n))
        if(!(n % i)) {
            ans.push_back((node){i, r / i, g / i});
            if(i != n / i) ans.push_back((node){n / i, r / (n / i), g / (n / i)});
        }
    sort(ans.begin(), ans.end());
    F(int, i, 0, (int)ans.size() - 1) printf("%d %d %d\n", ans[i].p, ans[i].ri, ans[i].gi);
    return 0;
}