Submission #1004772

#TimeUsernameProblemLanguageResultExecution timeMemory
1004772ProtonDecay314Robots (IOI13_robots)C++17
100 / 100
841 ms41044 KiB
#include<bits/stdc++.h>
// #define DEBUG
#ifndef DEBUG
#include "robots.h" 
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
typedef vector<int> vi;

vi to_vec(int arr[], int sz) {
    vi res(sz, 0);
    for(int i = 0; i < sz; i++) {
        res[i] = arr[i];
    }

    return res;
}

struct toy {
    int w;
    int s;
    int wi;
    int si;

    bool operator<(const toy& other) const {
        return si < other.si;
    }
};

int get_flimsiest_robot(const vi& robots, int val) {
    if(robots.size() == 0) return 0;
    int l = -1, r = robots.size();

    while(r - l > 1) {
        int m = (l + r) >> 1;
        if(robots[m] > val) r = m;
        else l = m;
    }

    return r;
}

bool poss(const vector<toy>& toys, int a, int b, int t, int d) {
    // Check if possible for a certain max duration d
    priority_queue<toy> q;

    int p1 = 0, p2 = 0;

    for(int i = 0; i < a; i++) {
        #ifdef DEBUG
        cout << "POINTERS: " << p1 << " " << p2 << endl;
        #endif

        // Move pointer 1 to the first toy whose wi equals i
        while(p1 < t && toys[p1].wi < i) p1++; // ! oop, I did toys[p1].wi > i haha
        p2 = p1;

        while(p2 < t && toys[p2].wi <= i) p2++;

        // Add these new toys to the priority queue
        for(int j = p1; j < p2; j++) {
            q.push(toys[j]);
        }

        // Assign "d" of these toys to the current weak robot wr[i]
        // (i.e., pop d times from the priority queue)
        for(int j = 0; j < d; j++) {
            if(q.empty()) break;
            #ifdef DEBUG
            cout << q.top().si << endl;
            #endif
            q.pop();
        }
    }
    assert(p2 == t || toys[p2].wi == a);
    
    // Push the toys that cannot be handled by any weak robot
    // These can potentially be handled by small robots though
    for(int i = p2; i < t; i++) {
        q.push(toys[i]);
    }

    // Now, we've assigned some toys to the weak robots
    // We now assign the rest to the small robots

    #ifdef DEBUG
    cout << "NUM TOYS TO SMALL: " << q.size() << endl;
    #endif

    if(q.empty()) return true;

    int cur_ind = b - 1;

    while(cur_ind >= 0) {
        if(q.top().si > cur_ind) return false;

        #ifdef DEBUG
        cout << "CUR SI: " << q.top().si << endl;
        #endif

        for(int i = 0; i < d; i++) {
            if(q.empty()) return true;
            q.pop();
        }
        if(q.empty()) return true;

        cur_ind--;
    }

    return q.empty();
}

// IOI Function Signatures
int putaway(int A, int B, int T, int X[], int Y[], int W[], int S[]) {
    if(A == 0) return putaway(B, A, T, Y, X, S, W);
    int a = A, b = B, t = T;
    // x is weight, y is size
    vi x = to_vec(X, a), y = to_vec(Y, b);


    // Sorting robots
    sort(x.begin(), x.end());
    sort(y.begin(), y.end());

    // Storing Toys
    vector<toy> toys;
    toys.reserve(t);
    for(int i = 0; i < t; i++) {
        toys.push_back({W[i], S[i], 0, 0});
    }

    // Binary searching to get the index of the first robot that can handle this
    for(int i = 0; i < t; i++) {
        toys[i].wi = get_flimsiest_robot(x, toys[i].w);
        toys[i].si = get_flimsiest_robot(y, toys[i].s); // ! CAREFUL! You put "x" instead of "y" ;-;

        // No robot can pick this up, return -1
        if(toys[i].wi == a && toys[i].si == b) return -1;
    }

    // Sort the toys, first from lightest to heaviest, then largest to smallest
    sort(toys.begin(), toys.end(), [](toy a, toy b) {
        return a.wi < b.wi || (a.wi == b.wi && a.si > b.si);
    });

    int l = 0, r = t + 1;
    while(r - l > 1) {
        int m = (l + r) >> 1;

        #ifdef DEBUG
        cout << "TESTING " << m << endl;
        #endif

        if(poss(toys, a, b, t, m)) r = m;
        else l = m;
    }

    return (r == t + 1 ? -1 : r);
};

// Driver Function
#ifdef DEBUG
int main() {
    int a, b, t;
    cin >> a >> b >> t;

    vi x(a, 0);
    vi y(b, 0);
    for(int& v : x) {
        cin >> v;
    }
    for(int& v : y) {
        cin >> v;
    }

    vi w(t, 0);
    vi s(t, 0);

    for(int i = 0; i < t; i++) {
        cin >> w[i] >> s[i];
    }

    cout << putaway(a, b, t, &x[0], &y[0], &w[0], &s[0]) << endl;

    return 0;
}
#endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...