제출 #1242221

#제출 시각아이디문제언어결과실행 시간메모리
1242221noyancanturk메시지 (IOI24_message)C++20
61.19 / 100
948 ms872 KiB
#include "message.h"

#include<bits/stdc++.h>
using namespace std;

#define pb push_back

void send_message(vector<bool>m,vector<bool>c){
  // cerr<<"enter1\n";
  srand(1);
  int maybe=31;
  int bad[31]{},trust[31]{},accuse[31]{},haveinfo[31]{};
  for(int i=0;i<31;i++){
    trust[i]=1<<i;
  }
  #define has(mask,i) ((mask>>i)&1)
  while(16<maybe){
    vector<bool>tosend(31,0);
    int edges[31];
    int did=0;
    for(int i=0;i<31;i++){
      edges[i]=-1;
      if(bad[i])continue;
      vector<int>noinfo;
      for(int j=0;j<31;j++){
        if(bad[j])continue;
        int nope=0;
        for(int k=0;k<31;k++){
          if(has(trust[i],k)&&has(haveinfo[k],j)){
            nope=1;
            break;
          }
        }
        if(!nope){
          noinfo.pb(j);
        }
      }
      if(noinfo.size()){
        edges[i]=noinfo[rand()%noinfo.size()];
        haveinfo[i]|=1<<edges[i];
        did++;
      }
    }
    // cerr<<did<<'\n';
    // for(int i=0;i<31;i++){
    //   cerr<<c[i]<<' '<<bad[i]<<' '<<__builtin_popcount(trust[i])<<' ';
    //   for(int j=0;j<31;j++){
    //     cerr<<has(trust[i],j);
    //   }cerr<<'\n';
    // }cerr<<'\n';
    // for(int i=0;i<31;i++){
    //   for(int j=0;j<31;j++){
    //     if(!c[i]&&c[j]&&has(trust[i],j)){
    //       cerr<<"what "<<i<<' '<<j<<'\n';
    //       assert(0);
    //     }
    //   }
    // }
    // assert(did);
    for(int i=0;i<31;i++){
      if(edges[i]!=-1)tosend[i]=!c[edges[i]];
    }
    vector<bool>sent=send_packet(tosend);
    for(int i=0;i<31;i++){
      if(edges[i]!=-1){
        if(sent[i]==1){
          trust[i]|=1<<edges[i];
        }else{
          accuse[i]|=1<<edges[i];
        }
      }
    }
    int change=1;
    while(change){
      change=0;
      for(int i=0;i<31;i++){
        for(int j=0;j<31;j++){
          if(has(trust[i],j)&&((trust[i]|trust[j])!=trust[i]||(accuse[i]|accuse[j])!=accuse[i])){
            trust[i]|=trust[j];
            accuse[i]|=accuse[j];
            change=1;
          }
        }
      }
    }
    for(int i=0;i<31;i++){
      if(16<__builtin_popcount(trust[i])||15<__builtin_popcount(accuse[i])||(trust[i]&accuse[i])||has(accuse[i],i)){
        bad[i]=1;
      }
    }
    change=1;
    while(change){
      for(int i=0;i<31;i++){
        change=0;
        if(bad[i])continue;
        for(int j=0;j<31;j++){
          if(has(trust[i],j)&&bad[j]){
            bad[i]=1;
            maybe--;
            change=1;
            break;
          }
        }
      }
    }
    for(int i=0;i<31;i++){
      haveinfo[i]=trust[i]|accuse[i];
    }
    for(int i=0;i<31;i++){
      if(!bad[i]&&__builtin_popcount(trust[i])==16){
        int ok=0;
        for(int j=0;j<31;j++){
          if(has(trust[i],j)&&has(trust[j],i)){
            ok++;
          }
        }
        if(ok==16){
          for(int j=0;j<31;j++){
            bad[j]=!has(trust[i],j);
          }
          maybe=16;
          break;
        }
      }
    }
  }
  vector<int>good;
  for(int i=0;i<31;i++){
    assert(bad[i]==c[i]);
    if(!bad[i]){
      good.pb(i);
    }
  }
  int n=m.size();
  vector<bool>tosend(31,0);
  for(int i=0;i<16;i++){
    tosend[good[i]]=has(n,i);
  }
  send_packet(tosend);
  for(int i=0;i<n;){
    for(int j=0;j<16;j++,i++){
      if(n<=i)tosend[good[j]]=0;
      else tosend[good[j]]=m[i];
    }
    send_packet(tosend);
  }
}

vector<bool>receive_message(vector<vector<bool>>ms){
  srand(1);
  int maybe=31;
  int bad[31]{},trust[31]{},accuse[31]{},haveinfo[31]{};
  for(int i=0;i<31;i++){
    trust[i]=1<<i;
  }
  int nxt=0;
  #define has(mask,i) ((mask>>i)&1)
  while(16<maybe){
    vector<bool>tosend(31,0);
    int edges[31];
    for(int i=0;i<31;i++){
      edges[i]=-1;
      if(bad[i])continue;
      vector<int>noinfo;
      for(int j=0;j<31;j++){
        if(bad[j])continue;
        int nope=0;
        for(int k=0;k<31;k++){
          if(has(trust[i],k)&&has(haveinfo[k],j)){
            nope=1;
            break;
          }
        }
        if(!nope){
          noinfo.pb(j);
        }
      }
      if(noinfo.size()){
        edges[i]=noinfo[rand()%noinfo.size()];
        haveinfo[i]|=1<<edges[i];
      }
    }
    vector<bool>sent=ms[nxt++];
    for(int i=0;i<31;i++){
      if(edges[i]!=-1){
        if(sent[i]==1){
          trust[i]|=1<<edges[i];
        }else{
          accuse[i]|=1<<edges[i];
        }
      }
    }
    int change=1;
    while(change){
      change=0;
      for(int i=0;i<31;i++){
        for(int j=0;j<31;j++){
          if(has(trust[i],j)&&((trust[i]|trust[j])!=trust[i]||(accuse[i]|accuse[j])!=accuse[i])){
            trust[i]|=trust[j];
            accuse[i]|=accuse[j];
            change=1;
          }
        }
      }
    }
    for(int i=0;i<31;i++){
      if(16<__builtin_popcount(trust[i])||15<__builtin_popcount(accuse[i])||(trust[i]&accuse[i])||has(accuse[i],i)){
        bad[i]=1;
      }
    }
    change=1;
    while(change){
      for(int i=0;i<31;i++){
        change=0;
        if(bad[i])continue;
        for(int j=0;j<31;j++){
          if(has(trust[i],j)&&bad[j]){
            bad[i]=1;
            maybe--;
            change=1;
            break;
          }
        }
      }
    }
    for(int i=0;i<31;i++){
      haveinfo[i]=trust[i]|accuse[i];
    }
    for(int i=0;i<31;i++){
      if(!bad[i]&&__builtin_popcount(trust[i])==16){
        int ok=0;
        for(int j=0;j<31;j++){
          if(has(trust[i],j)&&has(trust[j],i)){
            ok++;
          }
        }
        if(ok==16){
          for(int j=0;j<31;j++){
            bad[j]=!has(trust[i],j);
          }
          maybe=16;
          break;
        }
      }
    }
  }
  vector<int>good;
  for(int i=0;i<31;i++){
    if(!bad[i]){
      good.pb(i);
    }
  }
  int n=0;
  vector<bool>tosend=ms[nxt++];
  for(int i=0;i<16;i++){
    n|=int(tosend[good[i]])<<i;
  }
  vector<bool>m(n);
  for(int i=0;i<n;){
    assert(nxt<ms.size());
    tosend=ms[nxt++];
    for(int j=0;j<16;j++,i++){
      if(n<=i)break;
      else m[i]=tosend[good[j]];
    }
  }
  return m;
}

// void send_message(std::vector<bool> M, std::vector<bool> C) {
//   std::vector<bool> A(31, 0);
//   send_packet(A);
// }

// std::vector<bool> receive_message(std::vector<std::vector<bool>> R) {
//   return std::vector<bool>({0, 1, 1, 0});
// }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...