제출 #1276776

#제출 시각아이디문제언어결과실행 시간메모리
1276776avighna메시지 (IOI24_message)C++20
0 / 100
3190 ms824 KiB
#include <bits/stdc++.h>

std::vector<bool> send_packet(std::vector<bool> A);

void send_message(std::vector<bool> M, std::vector<bool> C) {
  auto hash = [&](const std::string &data) {
    uint32_t hash = 2166136261;
    for (auto &i : data) {
      hash = (hash ^ i) * 16777619;
    }
    return hash;
  };

  int bits = 0, i = 0;
  while (bits == 0) {
    bits += !C[i];
    i += !bits;
  }
  int channel = i;

  std::string c_str(31, '0');
  for (int i = 0; i < 31; ++i) {
    c_str[i] = C[i] + '0';
  }

  std::string data, ans_str;
  int cur = 0;
  auto push_bit = [&](bool x) {
    ans_str.push_back(x + '0');
    while (C[cur % 31]) {
      data.push_back('0'), cur++;
    }
    if (cur / 31 < 31 and cur % 31 == channel) {
      data.push_back(c_str[cur / 31]), cur++;
    }
    while (C[cur % 31]) {
      data.push_back('0'), cur++;
    }
    data.push_back(x + '0'), cur++;
  };

  auto push_num = [&](int x, int bits) {
    for (int i = 0; i < bits; ++i) {
      push_bit(x & 1 << i);
    }
  };

  push_num(M.size(), 16);
  for (int i = 0; i < M.size(); ++i) {
    push_bit(M[i]);
  }

  push_num(hash(ans_str), 32);

  while (cur / 31 < 31) {
    push_bit(0);
  }
  while (cur % 31 != 0) {
    data.push_back('0'), cur++;
  }

  auto send = [&](const std::string &s) {
    std::vector<bool> a(s.length());
    for (int i = 0; i < s.length(); ++i) {
      a[i] = s[i] == '1';
    }
    send_packet(a);
  };
  auto send_stream = [&]() {
    for (int i = 0; i < data.length(); i += 31) {
      send(data.substr(i, 31));
    }
  };
  send_stream();
}

std::vector<bool> receive_message(std::vector<std::vector<bool>> R) {
  auto hash = [&](const std::string &data) {
    uint32_t hash = 2166136261;
    for (auto &i : data) {
      hash = (hash ^ i) * 16777619;
    }
    return hash;
  };

  for (int channel = 0; channel < 31; ++channel) {
    int cur = 0;
    std::vector<bool> C(31);
    for (int i = 0; i < 31; ++i) {
      C[i] = R[cur + i][channel];
    }

    int j = 0;
    int base_cur = cur;
    std::string ans_str;
    auto recv_bit = [&](bool push) {
      while (C[j]) {
        cur += (j + 1) / 31, j = (j + 1) % 31;
      }
      if ((cur - base_cur) < 31 and j == channel) {
        cur += (j + 1) / 31, j = (j + 1) % 31;
      }
      while (C[j]) {
        cur += (j + 1) / 31, j = (j + 1) % 31;
      }
      if (cur > R.size()) {
        return 0;
      }
      int ans = R[cur][j];
      cur += (j + 1) / 31, j = (j + 1) % 31;
      if (push) {
        ans_str.push_back(ans + '0');
      }
      return ans;
    };

    auto recv_num = [&](int bits) {
      int x = 0;
      for (int i = 0; i < bits; ++i) {
        x += recv_bit(bits == 16) << i;
      }
      return x;
    };

    int size = recv_num(16);
    if (size > 1024) {
      continue;
    }
    std::vector<bool> ans(size);
    for (int i = 0; i < size; ++i) {
      ans[i] = recv_bit(true);
    }

    if (hash(ans_str) == recv_num(32)) {
      return ans;
    }
  }
  return {}; // will never happen
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...