제출 #1306640

#제출 시각아이디문제언어결과실행 시간메모리
1306640Davdav1232Flight to the Ford (BOI22_communication)C++20
15 / 100
134 ms3012 KiB
#include"communication.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<pii> vii;




// void __attribute__((noreturn)) __attribute__((format(printf, 1, 2))) result(const char *msg, ...)
// {
//     va_list args;
//     va_start(args, msg);
//     vfprintf(stdout, msg, args);
//     fprintf(stdout, "\n");
//     va_end(args);
//     exit(0);
// }

// namespace
// {
//     enum { ENCODE, DECODE } current_phase;
//     int N, X;
//     vector<int> signals;
//     size_t cursor = 0;
//     bool flipped = false;
// }

// int send(int s)
// {
//     if(current_phase == DECODE or (s != 0 and s != 1))
//         result("Invalid send.");

//     printf("send(%d) -> ", s); fflush(stdout);
//     int answer;
//     if(scanf("%d", &answer) != 1 or (answer != 0 and answer != 1))
//         result("Invalid reply to send.");

//     bool flipped_now = (s != answer);
//     if(flipped and flipped_now)
//         result("Invalid reply to send");
//     flipped = flipped_now;

//     signals.push_back(answer);
//     if(signals.size() > (size_t) 250)
//         result("Looks (and smells) fishy.");
//     return signals.back();
// }

// int receive()
// {
//     if(current_phase == ENCODE)  result("Invalid receive.");
//     if(cursor >= signals.size()) result("Assistant waiting for Godot.");
//     int r = signals[cursor++];
//     printf("receive() -> %d\n", r);
//     return r;
// }


bool init=0;
vi fib={0, 1};

int find_fib(int len, vi x){
    if(len==0) return 0;
    int ans=0;
    if(x[len-1]==1){
        ans+=fib[len+1];
    }
    x.pop_back();
    return ans+find_fib(len-1, x);
}

vi gen_fib(int len, int x){
    vi ans;
    while(len){
        if(x>=fib[len+1]){
            ans.push_back(1);
            x-=fib[len+1];
        }
        else ans.push_back(0);
        len--;
    }
    return ans;
}

void encode(int n, int x){
    if(!init){
        init=1;
        int sz=2;
        while(fib[sz-1]<(1<<30)){
            fib.push_back(fib[sz-1]+fib[sz-2]);
            sz++;
        }
    }
    x--;
    if(n==5){
        int a = (x >> 1) & 1;
        int b = x & 1;

        int c = send(a); // actual received value
        int d = send(b); // actual received value

        int NOT = 3 - 2*c - d; // number excluded
        int new_x = (x < NOT) ? x+1 : x; // map remaining numbers to 0..3
        //cout<<new_x;
        encode(4, new_x);
        return;
    }

    if(n>3){
        int a=1;
        int l=0;
        while(a<n){
            a*=2;
            l++;
        }
        //I need to send them the thing
        vi out(l, 0);
        for(int i=0; i<l; i++){
            if((1<<(l-i-1))&x) out[i]=1;
        }
        vi err(l);
        for(int i=0; i<l; i++) err[i]=(send(out[i])!=out[i]);
        reverse(err.begin(), err.end());
        //Now I need to send out the error
        int new_x=find_fib(l, err);
        encode(fib[l+2], new_x+1);
        return;
    }
    if(x==0){
        send(0);
        send(0);
        send(0);
        send(0);
    }
    if(x==1){
        send(0);
        send(1);
        send(1);
        send(0);
    }
    if(x==2){
        send(1);
        send(0);
        send(0);
        send(1);
    }
}


pii decode(int n){
    if(!init){
        init=1;
        int sz=2;
        while(fib[sz-1]<(1<<30)){
            fib.push_back(fib[sz-1]+fib[sz-2]);
            sz++;
        }
    }
    if(n==5){ // convert to 0-indexed
        int c = receive();
        int d = receive();

        int NOT = 3 - 2*c - d;
        //cout<<NOT; // excluded number (0-indexed)
        pii t = decode(4); 
        //cout<<t.first<<" "<<t.second;   // t.first and t.second are 1-indexed
        if(t.first - 1 >= NOT) t.first++;   // adjust if >= excluded
        if(t.second - 1 >= NOT) t.second++; // adjust if >= excluded

        return t;

    }

    if(n>3){
        int a=1;
        int l=0;
        while(a<n){
            a*=2;
            l++;
        }
        vector<int> inp(l);
        for(int i=0; i<l; i++) inp[i]=receive();
        //I need to xor this with the real thing
        pii e=decode(fib[l+2]);
        e.first--;
        e.second--;

        pii pot={0, 0};
        for(int i=0; i<l; i++){
            if(inp[i]){
                pot.first+=1<<(l-i-1);
                pot.second+=1<<(l-i-1);
            }
        }
        //I need to xor the options
        vi f=gen_fib(l, e.first);
        vi s=gen_fib(l, e.second);
        for(int i=0; i<l; i++){
            if(f[i]){
                pot.first^=1<<(l-i-1);
            }
            if(s[i]){
                pot.second^=1<<(l-i-1);
            }
        }
        pot.first+=1;
        pot.second+=1;
        return pot;
    }
    int a, b, c, d;
    a=receive();
    b=receive();
    c=receive();
    d=receive();
    if(a==0 && b==1){
        //1 0 not possible
        return {2, 1};
    }
    if(a==1 && b==0){
        return {1, 3};
    }
    if(a==1 && b==1){
        return {2, 3};
    }
    if(c==1 && d==0){
        //1 0 not possible
        return {2, 1};
    }
    if(c==0 && d==1){
        return {1, 3};
    }
    if(c==1 && d==1){
        return {2, 3};
    }
    //now they are 0, 0 which means it can't be 0110
    return {1, 3};
    //a and b are 0. if I tried to send 1, that means
}









// int main()
// {
//     if(scanf("%d %d", &N, &X) != 2 or X < 1 or X > N)
//         result("Invalid input.");

//     current_phase = ENCODE;
//     encode(N, X);
//     current_phase = DECODE;
//     auto r = decode(N);
//     //cout<<"\n"<<r.first<<" "<<r.second;

//     if(r.first < 1 or r.first > N or r.second < 1 or r.second > N)
//         result("Invalid answer.");

//     if(r.first == X or r.second == X)
//         result("Correct: %d signals sent.", (int) signals.size());
//     else
//         result("Wrong answer.");
// }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...