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

来源:互联网 发布:方可软件官网 编辑:程序博客网 时间:2024/06/05 02:17

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;}
0 0
原创粉丝点击