Submission #1357275

#TimeUsernameProblemLanguageResultExecution timeMemory
1357275yogesh_saneUnscrambling a Messy Bug (IOI16_messy)C++20
100 / 100
1 ms580 KiB
#include "messy.h"
#include <vector>
#include <string>

using namespace std;

/**
 * The goal is to find where each index 'i' ends up in the scrambled version.
 * We use a Divide and Conquer approach:
 * 1. "Tag" indices in the first half of a range.
 * 2. Later, "Check" which scrambled positions have that tag.
 */

void encode_range(int start, int end, int n) {
    if (start + 1 >= end) return; // Base case: range of size 1

    int mid = start + (end - start) / 2;
    
    // Create a "mask" where only bits in our current [start, end) are '0'
    string mask(n, '1');
    for (int i = start; i < end; i++) {
        mask[i] = '0';
    }

    // "Add" elements to the set to mark everything in the LEFT half
    for (int i = start; i < mid; i++) {
        string query = mask;
        query[i] = '1';
        add_element(query);
    }

    // Recursively handle the left and right halves
    encode_range(start, mid, n);
    encode_range(mid, end, n);
}

void decode_range(int start, int end, int n, const vector<int>& scrambled_indices, vector<int>& mapping) {
    if (start + 1 >= end) {
        // We've narrowed it down to a single position!
        // This scrambled position corresponds to the original index 'start'.
        mapping[scrambled_indices[0]] = start;
        return;
    }

    int mid = start + (end - start) / 2;

    // Create a mask where only the scrambled positions we are currently 
    // considering are set to '0'.
    string mask(n, '1');
    for (int pos : scrambled_indices) {
        mask[pos] = '0';
    }

    vector<int> left_half_positions;
    vector<int> right_half_positions;

    for (int pos : scrambled_indices) {
        string query = mask;
        query[pos] = '1';

        // If the system recognizes this pattern, it was one we "tagged"
        // in the encode phase as being in the left half.
        if (check_element(query)) {
            left_half_positions.push_back(pos);
        } else {
            right_half_positions.push_back(pos);
        }
    }

    decode_range(start, mid, n, left_half_positions, mapping);
    decode_range(mid, end, n, right_half_positions, mapping);
}

vector<int> restore_permutation(int n, int w, int r) {
    // Phase 1: Encode the hierarchy into the messy set
    encode_range(0, n, n);
    compile_set();

    // Phase 2: Decode the hierarchy by checking scrambled positions
    vector<int> initial_positions;
    for (int i = 0; i < n; i++) initial_positions.push_back(i);
    
    vector<int> result_permutation(n);
    decode_range(0, n, n, initial_positions, result_permutation);

    return result_permutation;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...