제출 #1354289

#제출 시각아이디문제언어결과실행 시간메모리
1354289tickcrossyMessage (IOI24_message)C++20
29.32 / 100
382 ms824 KiB
#include <vector>

using namespace std;

// 选手不需要实现该函数,这里仅作声明以供调用
vector<bool> send_packet(vector<bool> A);

// Aisha 的发送策略
void send_message(vector<bool> M, vector<bool> C) {
    // 阶段一:用 31 个数据包,绝对安全地将数组 C 传给 Basma
    for (int i = 0; i < 31; i++) {
        vector<bool> A(31, C[i]);
        send_packet(A);
    }

    // 阶段二:传输消息长度 S 以及消息内容 M
    int S = M.size();
    vector<bool> data;
    
    // 用 11 个比特编码长度 S (1024 需要 11 位)
    for (int i = 0; i < 11; i++) {
        data.push_back((S >> i) & 1);
    }
    
    // 放入实际的消息 M
    for (int i = 0; i < S; i++) {
        data.push_back(M[i]);
    }
    
    // 补齐到 16 的倍数,方便每次发送 16 个比特
    while (data.size() % 16 != 0) {
        data.push_back(0);
    }

    // 找出 16 个安全的列 (C[i] == 0 代表安全)
    vector<int> safe_cols;
    for (int i = 0; i < 31; i++) {
        if (!C[i]) {
            safe_cols.push_back(i);
        }
    }

    // 每次拿出 16 个比特发出去
    for (size_t i = 0; i < data.size(); i += 16) {
        vector<bool> A(31, 0); // 被篡改的位置填 0,无所谓
        for (int j = 0; j < 16; j++) {
            A[safe_cols[j]] = data[i + j];
        }
        send_packet(A);
    }
}

// Basma 的接收策略
vector<bool> receive_message(vector<vector<bool>> R) {
    vector<bool> C(31);
    
    // 阶段一:从前 31 个数据包中恢复掩码 C
    for (int i = 0; i < 31; i++) {
        int count = 0;
        for (int j = 0; j < 31; j++) {
            if (R[i][j]) count++;
        }
        // 如果 1 的个数 >= 16,则说明原本发出的就是 1 (因为安全位有 16 个)
        C[i] = (count >= 16);
    }

    // 找出安全的 16 个位置
    vector<int> safe_cols;
    for (int i = 0; i < 31; i++) {
        if (!C[i]) {
            safe_cols.push_back(i);
        }
    }

    // 阶段二:从后续的数据包里在安全位置上提取比特
    vector<bool> data;
    for (size_t p = 31; p < R.size(); p++) {
        for (int j = 0; j < 16; j++) {
            data.push_back(R[p][safe_cols[j]]);
        }
    }

    // 读取前 11 个比特来还原消息长度 S
    int S = 0;
    for (int i = 0; i < 11; i++) {
        if (data[i]) {
            S |= (1 << i);
        }
    }

    // 根据还原出的长度 S,截取实际的消息 M
    vector<bool> M(S);
    for (int i = 0; i < S; i++) {
        M[i] = data[11 + i];
    }

    return M;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...