This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
// partially_correct/solution.cpp
#include "message.h"
#include <bits/stdc++.h>
using namespace std;
/*
 * The solution start by identifing one on allies in 4 rounds
 * There will be 16+8+4+2 = 30 wasted bits and 16*4-30 = 34 bits that can be used to transmit the message
 * Use 5 of them to indicate the number of bits you need to remove from the message. (29 bits remaining)
 * in 29 rounds you can send for each bit whether it's ally or spy and use the remaining bits for the message
 * You can skip the ally you already know and the last bit is already known so you need exactly 29 more rounds.
 * If the message will take partial bits from 29 rounds we send [11111] [len of actual message], 
 * otherwise 5 bits are enough to indicate number of needed bits to be removed.
*/
const int BITS=31;
void send_message(std::vector<bool> message, std::vector<bool> positions) {
    vector<int> cur_subset(BITS), cur_allies, free_allies;
    iota(cur_subset.begin(), cur_subset.end(), 0);
    for(int i=0;i<BITS;i++)
        if(positions[i]==0) cur_allies.push_back(i);
    int free_bits=(16*4-(16+8+4+2 + 5));
    vector<bool> sent_bits;
    if ((int)message.size() <= free_bits - 9 + 29*15) {
        for(int i=0;i<5;i++) sent_bits.push_back(1);
        int msg_len = message.size();
        for(int i=0;i<9;i++) {
            sent_bits.push_back(msg_len%2);
            msg_len/=2;
        }
        for(int i=0;i<(int)message.size();i++) sent_bits.push_back(message[i]);
        while((int)sent_bits.size() < free_bits + 29*15) sent_bits.push_back(0);
    } else {
        int rounds = ((int)message.size() + 5 + 15) / 16;
        int remove_bits = rounds*16 - (message.size()), tmp_rem=remove_bits;
        for(int i=0;i<5;i++) {
            sent_bits.push_back(tmp_rem%2);
            tmp_rem/=2;
        }
        for(int i=0;i<(int)message.size();i++) sent_bits.push_back(message[i]);
        while(sent_bits.size() % 16) {sent_bits.push_back(0);}
    }
    int cur_pos = 0;
    for(int _=0;_<4;_++)
    {
        vector<bool> msg(BITS);
        for(int x=0;x<(int)cur_allies.size()/2;x++) msg[cur_allies[x]]=0;
        for(int x=cur_allies.size()/2;x<(int)cur_allies.size();x++) msg[cur_allies[x]]=1;
        sort(free_allies.begin(), free_allies.end());
        for(int i:free_allies) 
            msg[i] = sent_bits[cur_pos++];
        msg=send_packet(msg);
        int co[2]={};
        for(int i:cur_subset) co[msg[i]]++;
        int used_bit = co[0]<co[1]? 0 : 1;
        vector<int> new_subset, new_allies;
        for(int i:cur_subset) {
            if(msg[i] == used_bit) new_subset.push_back(i);
        }
        for(int i:cur_allies) {
            if(msg[i] == used_bit) new_allies.push_back(i);
            else free_allies.push_back(i);
        }
        cur_subset = new_subset;
        cur_allies = new_allies;
    }
    
    assert(cur_allies.size() == 1);
    int known_ally = cur_allies[0];
    vector<bool> allies_positions;
    for(int i=0;i<BITS;i++)
    {
        if(i==known_ally) continue;
        allies_positions.push_back(positions[i]);
    }
    allies_positions.pop_back();
    for(int i=0;i<29;i++) {
        vector<bool> msg(BITS);
        for(int x=0;x<BITS;x++)
        {
            if(x==known_ally) msg[x]=allies_positions[i];
            else if(positions[x]==0) 
                msg[x] = sent_bits[cur_pos++];
        }
        send_packet(msg);
    }
    while(cur_pos < (int)sent_bits.size()) {
        vector<bool> msg(BITS);
        for(int i=0;i<BITS;i++) {
            if(positions[i]==0)
                msg[i]=sent_bits[cur_pos++];
        }
        send_packet(msg);
    }
}
std::vector<bool> receive_message(vector<vector<bool>> received_bits) {
    vector<int> cur_subset(BITS);
    iota(cur_subset.begin(),cur_subset.end(), 0);
    for(int r=0;r<4;r++) {
        int co[2]={};
        for(int i:cur_subset) co[received_bits[r][i]]++;
        int used_bit = co[0]<co[1]? 0 : 1;
        vector<int> new_subset;
        for(int i:cur_subset)
            if(received_bits[r][i] == used_bit) new_subset.push_back(i);
        cur_subset = new_subset;
    }
    assert(cur_subset.size() == 1);
    int known_ally = cur_subset[0];
    vector<bool> positions;
    int cur_ally=0, curtotal=15;
    for(int i=4;i<4+29;i++) {
        if(cur_ally == known_ally) {
            positions.push_back(0); cur_ally++;
        }
        positions.push_back(received_bits[i][known_ally]);
        cur_ally++; curtotal -= positions.back();
    }
    if(cur_ally==known_ally) positions.push_back(0); // Position before last is known ally
    positions.push_back(curtotal);
    if(positions.size()<31) positions.push_back(0); // Last position is known ally
    vector<int> ally_positions;
    for(int i=0;i<BITS;i++)
        if(positions[i]==0) ally_positions.push_back(i);
    vector<bool> msg;
    cur_subset = vector<int>(BITS);
    iota(cur_subset.begin(),cur_subset.end(), 0);
    for(int r=0;r<4;r++) {
        int bad[BITS]={};
        int co[2]={};
        for(int i:cur_subset) {bad[i] = 1; co[received_bits[r][i]]++;}
        int used_bit = co[0]<co[1]? 0 : 1;
        vector<int> new_subset;
        for(int i:cur_subset) {
            if(received_bits[r][i] == used_bit) {
                new_subset.push_back(i);
            }
        }
        cur_subset = new_subset;
        for(int i:ally_positions)
            if(!bad[i]) msg.push_back(received_bits[r][i]);
    }
    for(int i=4;i<4+29;i++) {
        for(int j:ally_positions) {
            if(j==known_ally) continue;
            msg.push_back(received_bits[i][j]);
        }
    }
    for(int i=4+29;i<(int)received_bits.size();i++) {
        for(int j:ally_positions) msg.push_back(received_bits[i][j]);
    }
    int case1=1;
    for(int i=0;i<5;i++) case1&=msg[i];
    if(case1) {
        int len=0;
        for(int i=9+5-1;i>=5;i--) {
            len*=2; len+=msg[i];
        }
        vector<bool> res;
        for(int i=9+5;i<9+5+len;i++)
            res.push_back(msg[i]);
        return res;
    } else {
        vector<bool> cur_msg;
        for(int i=5;i<(int)msg.size();i++) cur_msg.push_back(msg[i]);
        int rem=0;
        for(int i=4;i>=0;i--) {
            rem*=2; rem+=msg[i];
        }
        while(rem--) cur_msg.pop_back();
        return cur_msg;
    }
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |