CodeForces 670D2 Magic Powder - 2(二分+贪心)

http://codeforces.com/contest/670/problem/D2

简单的二分,二分所有可以做的饼干数,然后遍历就可以啦

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;

typedef long long LL;
#define N 210000
#define INF 0x3f3f3f3f
#define met(a, b) memset (a, b, sizeof(a))

struct node
{
    LL one, sum;///做一个饼干需要的材料和已经有的材料
    LL num, need;///当前材料可以做的饼干数和做剩下的材料
}p[N];

bool cmp (node a, node b)
{
    return a.num < b.num;
}

LL n, k, L, R;

LL Search ()
{
    LL l = L, r = R, maxn = 0;

    while (l<=r)
    {
        LL mid = (l+r)/2, S = 0;
        for (int i=0; i<n; i++)
        {
            if (p[i].num < mid)
            {
                S += p[i].one-p[i].need;
                if (mid>p[i].num)
                    S += (mid-1-p[i].num)*p[i].one;

                if (S > k) break;///第一次没加上这个判断条件WA在第128组测试数据上了
            }
        }

        if (S <= k)
        {
            maxn = max (maxn, mid);
            l = mid+1;
        }
        else r = mid-1;
    }
    return maxn;
}

void Solve ()
{
    sort (p, p+n, cmp);

    L = R = p[0].num;

    for (int i=0; i<n; i++)
        R = max (R, (k+p[i].need)/p[i].one+p[i].num);

   LL ans = Search();
   printf ("%I64d\n", ans);
}

int main ()
{
    while (scanf ("%I64d %I64d", &n, &k) != EOF)
    {
        met (p, 0);

        for (int i=0; i<n; i++)
            scanf ("%I64d", &p[i].one);

        for (int i=0; i<n; i++)
        {
            scanf ("%I64d", &p[i].sum);
            p[i].num = p[i].sum / p[i].one;
            p[i].need = p[i].sum % p[i].one;
        }

        Solve ();
    }
    return 0;
}


你可能感兴趣的:(CodeForces 670D2 Magic Powder - 2(二分+贪心))