UVA10277 - Boastin' Red Socks(枚舉+二分)

UVA10277 - Boastin' Red Socks(枚舉+二分)

題目鏈接

題目大意:現在有m只紅襪子,n只黑襪子,這樣總襪子total = n + m;現在給你p, q,確定n和m,使得從這些襪子中取兩隻都是紅襪子的概率等於p/q;如果沒有這樣的n和m滿足要求輸出impossible;

解題思路:m *(m - 1) / (total * (total - 1)) = p /q; 那麼我們只需要枚舉total,就可以解到m。但是會有精度誤差,貌似有解決的辦法,但是覺得沒法理解。後面看了另外的一種題接,二分m,因爲m > 1之後就是單調遞增的。所以只要之前處理掉特殊情況 m = 0,也就是p = 0的情況就可以了。

代碼:

#include <cstdio>
#include <cstring>
#include <cmath>

typedef long long ll;

ll gcd (ll a, ll b) {

    return (b == 0) ? a : gcd(b, a%b);
}

int main () {

    ll p, q, ans, P, Q;
    bool flag;
    while (scanf ("%lld%lld", &P, &Q) != EOF && (P || Q)) {

        flag = 0;
        if (P == 0) {
            printf ("0 2\n");
            continue;
        }

        if (P == Q) {
            printf("2 0\n");
            continue;
        }
        ans = gcd(P, Q);

        P /= ans;
        Q /= ans;
        ll m, total;
        int l, r; 
        for (total = 3; total <= 50000; total++) {

            ll N = total * (total - 1) * P, M;
            if (N % Q != 0)
                continue;
            N /= Q;

            l = 1; r = total;
            while (l < r) {
                m = (l + r) / 2;
                M = m * (m - 1);
                if (M < N)
                    l = m + 1;
                else if (M > N)
                    r = m;
                else {
                    flag = 1;
                    break;
                }
            }
            if (flag)
                break;
        }

        if (flag)
            printf ("%lld %lld\n", m, total - m);
        else
            printf ("impossible\n");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章