ECfinal-D-Ice Cream Tower-two points + greedy

Portal: https://vjudge.net/problem/Gym-101194D

The meaning of the question: In a pile of numbers, find a combination of many, so that the number of each combination is K, and after sorting, the latter one is twice the former;

Thought: Dichotomous, greedy; I can't think that greedy check is really sad. Here, just open another pre array to record the latest numbers of each group, and then one by one (if this group finds one, move to the next group to find one) to find out whether there is a subsequent number that meets the conditions.

Code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
typedef long long ll;
const int maxn = 3e5+8;
int k,n;
ll a[maxn];
ll pre[maxn];
bool check(int x)
{
    for(int i=1; i<=x; i++)
        pre[i] = a[i];
    int id = x + 1;
    for(int g = 1; g<=k - 1; g++)
    {
        for(int i=1; i<=x; i++)
        {
            if(id>n)return false;
            while(a[id] < 2 * pre[i])
            {
                    id++;
                    if(id>n)return false;
            }
            pre[i] = a[id];
            id++;
        }
    }
    return true;
}
int main(){
    int T;
    scanf("%d", &T);
    for(int t=1; t<=T; t++)
    {
        scanf("%d%d", &n, &k);
        for(int i = 1; i<=n;i++)
        {
            scanf("%lld" ,&a[i]);
        }
        sort(a+1, a+n+1);
        int le = 0,ri = n / k +1;
        while(le + 1 < ri)
        {
            int mid = le + (ri - le)/2;
            if(check(mid))
            {
                le = mid;
            }
            else ri = mid;
        }
        if (k== 1 )le = n;
        printf("Case #%d: %d\n",t,le);
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324905486&siteId=291194637