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;
}

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

时间: 2024-12-26 15:26:15

UVA10277 - Boastin' Red Socks(枚举+二分)的相关文章

TOJ-1324 Boastin&#39; Red Socks

You have a drawer that is full of two kinds of socks: red and black. You know that there are at least 2 socks, and not more than 50000. However, you do not know how many there actually are, nor do you know how many are red, or how many are black. (Yo

UVA 10277 Boastin&#39; Red Socks

1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 5 using namespace std; 6 7 unsigned int r,sum,p,q; 8 unsigned int st[50010][2]; 9 10 unsigned gcd(unsigned a,unsigned b) 11 { 12 return b?gcd(b,a%b):a; 13 } 14 /*哈希链表*/ 15 co

hdu4430之枚举+二分

Yukari's Birthday Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2549    Accepted Submission(s): 522 Problem Description Today is Yukari's n-th birthday. Ran and Chen hold a celebration party

CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。

1514: Packs Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 61  Solved: 4[Submit][Status][Web Board] Description Give you n packs, each of it has a value v and a weight w. Now you should find some packs, and the total of these value is max, total of

hdu 4430 Yukari&#39;s Birthday 枚举+二分

注意会超long long 开i次根号方法,te=(ll)pow(n,1.0/i); Yukari's Birthday Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3262    Accepted Submission(s): 695 Problem Description Today is Yukari's n-th birt

Eqs 折半枚举+二分查找 大水题

Eqs 题目抽象:a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0 (*),给出a1,a2,a3,a4,a5.    ai属于[-50,50]. 求有多少序列   x1,x2,x3,x4,x5 ,xi属于 [-50,50]-{0}. 思路:折半枚举+二分查找 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #inclu

poj 3977 Subset 枚举+二分

首先分成一半2^17和2^18,并且把其中一半变成相反数,然后枚举一半二分查找另一半,在找到的位置前后也找找. 这里用到了二级排序,有很多细节要处理,不多说了. 巨坑的一个地方就是,不能用系统的abs,要自己手写,简直坑死.. #include<cstdio> #include<algorithm> #include<iostream> #include<map> using namespace std; typedef long long ll; stru

POJ 3977Subset(枚举+二分)

Subset Time Limit: 30000MS   Memory Limit: 65536K Total Submissions: 1562   Accepted: 261 Description Given a list of N integers with absolute values no larger than 1015, find a non empty subset of these numbers which minimizes the absolute value of

Codeforces 496D Tennis Game 枚举+二分

题目链接:点击打开链接 题意: 给定n场比赛. 下面n个数字:表示该场是1获胜还是2获胜. 1.胜利者获得一分. 2.若已经决出整个赛季的胜负则比赛不会继续. 3.设要赢得这个赛季需要赢有s局,每局先获得t分的选手胜利. 问: 找出所有的(s,t)组合使得给定的n场比赛记录合法. 输出要排序. 枚举t. a数组存第一个人赢的哪些场次. b数组存第二个人赢的哪些场次. 设赢t分为一句.则判断 第一个人再赢t分是第几场,第二个人再赢t分是第几场. 显然先赢得t分的人赢了这场. 这样同时跑2个人的场数