제출 #1195006

#제출 시각아이디문제언어결과실행 시간메모리
1195006tutis메시지 (IOI24_message)C++20
66.69 / 100
1309 ms900 KiB
#include "message.h" #include <algorithm> #include <chrono> #include <iostream> #include <random> #include <bitset> #include <vector> #include <deque> #include <assert.h> #include <math.h> using namespace std; int counter = 0; const int bitsCnt = 10; bitset<31> seqs[1 << bitsCnt]; bitset<31> masks[200]; const int64_t seed1 = 5; int tests = 10000; bitset<31> globC; vector<bitset<16>> safeMasks{ 0b0000000011111111, 0b1111111100000000, 0b1111000011110000, 0b1100110011001100, 0b1010101010101010, 0b0101010101010101}; bitset<6> recov(bitset<11> x) { bitset<6> ret; for (int t = 0; t < 6; t++) { ret[t] = true; for (int i = 0; i < 11; i++) { if (x[i] && safeMasks[t][i]) { ret[t] = !ret[t]; } } } return ret; } bitset<11> recover(bitset<17> x, int *flip) { for (int i = -1; i < 17; i++) { if (i != -1) { x[i] = x[i] ^ true; } bitset<11> v = x.to_ullong(); bitset<6> rec = x.to_ullong() >> 11; if (recov(v) == rec) { *flip = i; return v; } if (i != -1) { x[i] = x[i] ^ true; } } *flip = -2; return {}; } bool initialized = false; void init() { counter = 0; if (!initialized) { mt19937_64 rng(seed1); for (int i = 0; i < (1 << bitsCnt); i++) { seqs[i] = bitset<31>(rng()); if (i % 2 == 1) { seqs[i] = ~seqs[i - 1]; } } for (int i = 0; i < 200; i++) { for (int j = 0; j < 31; j++) { masks[i] = rng(); } } } initialized = true; } bitset<31> send(bitset<31> A) { if (counter >= 199) { assert(false); } A = A ^ masks[counter]; vector<bool> Avector(31); for (int i = 0; i < 31; i++) { Avector[i] = A[i]; } vector<bool> recVector = send_packet(Avector); bitset<31> received; for (int j = 0; j < 31; j++) { received[j] = recVector[j]; } received = received ^ masks[counter]; counter++; return received; } struct X { bitset<31> C; }; bool subset(bitset<31> a, bitset<31> b) { return (a & b) == a; } deque<bool> prepareBits(vector<bool> M) { int offset = 1024 - M.size(); deque<bool> X; for (int i = 0; i < offset; i++) { X.push_back(1); } X.push_back(0); for (int v : M) { X.push_back(v); } while (!X.empty() && X.back() == 0) { X.pop_back(); } return X; } vector<bitset<31>> getSeqs(X x) { vector<bitset<31>> ret; for (bitset<31> v : seqs) { bool ok = true; for (bitset<31> w : ret) { if (v == w) { continue; } int possibleDiffs = ((v ^ w) & (~x.C)).count(); int possibleChanges = 15 - x.C.count(); if (possibleChanges * 2 >= possibleDiffs) { ok = false; break; } } if (ok) { ret.push_back(v); } } int v = 1; while (v * 2 <= int(ret.size())) { v *= 2; } while (int(ret.size()) > v) { ret.pop_back(); } return ret; } int sends = 0; void send_message(vector<bool> M, vector<bool> Cvect) { sends++; mt19937_64 rng(sends); init(); bitset<31> C; for (int i = 0; i < 31; i++) { C[i] = Cvect[i]; } globC = C; X x; deque<bool> X = prepareBits(M); while (x.C.count() < 14) { vector<bitset<31>> seqs = getSeqs(x); int s = 0; for (int i = 0; (1 << (i + 1)) <= seqs.size(); i++) { if (!X.empty() && X[0]) { s += 1 << i; } if (!X.empty()) { X.pop_front(); } } bitset<31> to_send = seqs[s]; for (int i = 0; i < 31; i++) { if (C[i]) { to_send[i] = rng() % 2; } } bool ok = false; bitset<31> resp = send(to_send); int s1 = 0; int ss = 0; for (bitset<31> seq : seqs) { bitset<31> diff = (resp ^ seq) | (x.C); if (diff.count() >= 16) { s1++; continue; } if (ok) { bitset<31> seq1 = seqs[s1]; bitset<31> diff1 = (resp ^ seq) | (x.C); bitset<31> dx = (seq ^ seq1) & (~x.C); if ((diff & dx).count() >= (diff1 & dx).count()) { s1++; continue; } } ok = true; ss = s1; s1++; } x.C = (resp ^ seqs[ss]) | (x.C); if (s != ss) { exit(0); } if (!ok) { exit(0); } if (counter > 100) { exit(0); } } while (x.C.count() == 14) { bitset<17> xx; for (int i = 0; i < 11; i++) { if (!X.empty()) { xx[i] = X[0]; X.pop_front(); } } bitset<6> y = recov(xx.to_ullong()); xx |= (bitset<17>(y.to_ullong()) << 11); bitset<31> to_send; int c = 0; for (int i = 0; i < 31; i++) { if (x.C[i] == false) { to_send[i] = xx[c]; c++; } } for (int i = 0; i < 31; i++) { if (C[i]) { to_send[i] = rng() % 2; } } bitset<17> xx_resp; bitset<31> resp = send(to_send); c = 0; for (int i = 0; i < 31; i++) { if (x.C[i] == false) { xx_resp[c] = resp[i]; c++; } } int flip; recover(xx_resp, &flip); if (flip == -2) { exit(0); } c = 0; for (int i = 0; i < 31; i++) { if (x.C[i] == false) { if (c == flip) { x.C[i] = true; break; } c++; } } } bitset<31> good = x.C.flip(); while (!X.empty()) { bitset<31> packet; for (int v = 0; v < 31; v++) { if (good[v]) { if (!X.empty()) { packet[v] = X[0]; X.pop_front(); } } } send(packet); } } std::vector<bool> receive_message(vector<vector<bool>> Rvect) { init(); vector<bitset<31>> R(Rvect.size()); for (int i = 0; i < int(Rvect.size()); i++) { bitset<31> b; for (int j = 0; j < 31; j++) { b[j] = Rvect[i][j]; } R[i] = b; } for (int i = 0; i < int(R.size()); i++) { R[i] = R[i] ^ masks[i]; } vector<bool> recX; X x; int i = 0; while (x.C.count() < 14) { bitset<31> resp = R[i]; i++; vector<bitset<31>> seqs = getSeqs(x); int s1 = 0; int ss = 0; bool ok = false; for (bitset<31> seq : seqs) { bitset<31> diff = (resp ^ seq) | (x.C); if (diff.count() >= 16) { s1++; continue; } if (ok) { bitset<31> seq1 = seqs[s1]; bitset<31> diff1 = (resp ^ seq) | (x.C); bitset<31> dx = (seq ^ seq1) & (~x.C); if ((diff & dx).count() >= (diff1 & dx).count()) { s1++; continue; } } ok = true; ss = s1; s1++; } x.C = (resp ^ seqs[ss]) | (x.C); if (!ok) { exit(0); } vector<bool> a; for (int i = 0; (1 << (i + 1)) <= seqs.size(); i++) { if ((ss & (1 << i)) != 0) { recX.push_back(true); } else { recX.push_back(false); } } } while (x.C.count() == 14) { bitset<17> xx_resp; bitset<31> resp = R[i]; i++; int c = 0; for (int i = 0; i < 31; i++) { if (x.C[i] == false) { xx_resp[c] = resp[i]; c++; } } int flip; bitset<11> recovered = recover(xx_resp, &flip); if (flip == -2) { exit(0); } for (int i = 0; i < 11; i++) { recX.push_back(recovered[i]); } c = 0; for (int i = 0; i < 31; i++) { if (x.C[i] == false) { if (c == flip) { x.C[i] = true; break; } c++; } } } bitset<31> good = x.C.flip(); for (; i < int(R.size()); i++) { for (int v = 0; v < 31; v++) { if (good[v]) { recX.push_back(R[i][v]); } } } int offset = 0; while (offset < int(recX.size()) && recX[offset]) { offset++; } vector<bool> answer; for (int i = offset + 1; i < int(recX.size()); i++) { answer.push_back(recX[i]); } while (answer.size() < 1025) { answer.push_back(0); } while ((1024 - int(answer.size())) != offset && answer.size() > 0) { answer.pop_back(); } return answer; } // vector<vector<bool>> sent; // int main() // { // mt19937_64 rng(5); // int maxQ = 0; // double avg = 0; // for (int i = 0; i < tests; i++) // { // vector<bool> msg(1024); // for (int i = 0; i < int(msg.size()); i++) // { // msg[i] = rng() % 2; // } // vector<bool> Cvect{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // shuffle(Cvect.begin(), Cvect.end(), rng); // send_message(msg, // Cvect); // vector<bool> received = receive_message(sent); // maxQ = max(maxQ, int(sent.size())); // avg += sent.size(); // if (msg != received) // { // cout << "maxQ: " << maxQ << " i: " << i << endl; // cout << "mismatch!" << endl; // for (int i : msg) // { // cout << i; // } // cout << endl; // for (int i : received) // { // cout << i; // } // cout << endl; // exit(0); // } // else // { // } // sent = {}; // } // cout << maxQ << " " << avg / tests << endl; // } // mt19937_64 rng(0); // vector<bool> send_packet(std::vector<bool> A) // { // for (int i = 0; i < 31; i++) // { // if (globC[i]) // { // A[i] = rng() % 2; // } // } // sent.push_back(A); // return A; // }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...