제출 #1338597

#제출 시각아이디문제언어결과실행 시간메모리
1338597julia_08Chika Wants to Cheat (EGOI22_cheat)C++20
71 / 100
4 ms836 KiB
#pragma GCC optimize("unroll-loops, O3")

#include <bits/stdc++.h>
#include "cheat.h"

using namespace std;

using pii = pair<int, int>;

using point = pii;
using segment = pair<pii, pii>;

int dp[8]; // dp de contagem, quantos números consigo fazer

vector<vector<segment>> segs;
map<segment, int> id;

bool to_init = true;

void print(segment s){
  // cout << "(" << s.first.first << " " << s.first.second << ") - (" << s.second.first << ", " << s.second.second << ")\n"; 
}

segment to_seg(int x){
  return segs[x / 4][x % 4];
}

point rotate(point p){
  return {2 - p.second, p.first};
}

segment rotate(segment s){

  segment r = {rotate(s.first), rotate(s.second)};
 
  if(r.first > r.second) swap(r.first, r.second);
  return r;

}

int rotate(int mask){

  int nmask = 0;

  for(int i=0; i<28; i++){
    if(mask & (1 << i)){
      int j = id[rotate(to_seg(i))];
      nmask += (1 << j);
    }
  }

  return nmask;

}

void add(segment s, vector<vector<segment>> &segs){

  segs.push_back({});

  for(int i=0; i<4; i++){
    segs.back().push_back(s);    
    s = rotate(s);
  }

}

void add(int s, vector<int> &rot){

  for(int i=0; i<4; i++){
    rot.push_back(s);
    s = rotate(s);
  }

}

void init(){

  dp[0] = 0;

  for(int i=1; i<=7; i++) dp[i] = 3 * (1 << 4 * (i - 1)) + 4 * dp[i - 1];

  // cout << "dp[7] = " << dp[7] << endl; 

  // segmentos primitivos de cada um dos 7 grupos:

  id.clear();
  segs.clear();

  add({{0, 0}, {0, 1}}, segs);
  add({{0, 0}, {1, 0}}, segs);
  add({{0, 0}, {1, 1}}, segs);
  add({{0, 0}, {2, 1}}, segs);

  add({{0, 1}, {1, 0}}, segs);
  add({{0, 1}, {2, 0}}, segs);

  add({{1, 0}, {1, 1}}, segs);
  
  for(int i=0; i<7; i++){
    for(int j=0; j<4; j++){
      id[segs[i][j]] = 4 * i + j;
    }
  }

}

int encode(int n, int pos){

  int bit[4] = {0, 0, 0, 0};
  
  for(int i=0; i<4; i++) bit[i] = (1 << (4 * (pos - 1) + i));

  int brute[4] = {0, bit[0] + bit[1] + bit[2] + bit[3], bit[0] + bit[2], bit[1] + bit[3]};

  int x = (1 << (4 * (pos - 1)));

  if(n < 3 * x){

    if(n < x) return n + bit[0];

    if(n < 2 * x) return (n - x) + bit[0] + bit[1];
    return (n - 2 * x) + bit[1] + bit[2] + bit[3];

  }

  n -= 3 * x;

  int cnt = dp[pos - 1];

  return encode(n - (n / cnt) * cnt, pos - 1) + brute[n / cnt];

}

int decode(int mask, int pos){

  int bit[4] = {0, 0, 0, 0};
  
  for(int i=0; i<4; i++) bit[i] = (1 << (4 * (pos - 1) + i));

  int brute[4] = {0, bit[0] + bit[1] + bit[2] + bit[3], bit[0] + bit[2], bit[1] + bit[3]};

  int x = (1 << (4 * (pos - 1)));

  int cur = 0;

  for(int i=0; i<4; i++) if(mask & bit[i]) cur += bit[i];

  int j = -1;

  for(int i=0; i<4; i++) if(cur == brute[i]) j = i;

  if(j != -1) return j * dp[pos - 1] + 3 * x + decode(mask, pos - 1);

  int cur_rot = 0, cnt = __builtin_popcount(cur) - 1;

  vector<int> rot; 

  if(cnt == 0) add(bit[0], rot);
  if(cnt == 1) add(bit[0] + bit[1], rot);
  if(cnt == 2) add(bit[1] + bit[2] + bit[3], rot); 

  int b = 4 * (pos - 1);

  for(int j=0; j<4; j++) if((cur >> b) == (rot[j] >> b)) cur_rot = 4 - j;

  mask &= (1 << b) - 1;

  for(int j=0; j<cur_rot; j++) mask = rotate(mask);

  return mask + cnt * x;

}

vector<segment> BuildPattern(int n){

  if(to_init) init();
  to_init = false;

  int mask = encode(n, 7);
    
  vector<segment> ret;

  for(int i=0; i<28; i++){
    if(mask & (1 << i)){
      ret.push_back(to_seg(i));
    }
  }

  return ret;

}

int GetCardNumber(vector<segment> p){

  if(to_init) init();
  to_init = false;

  int mask = 0;

  for(auto &s : p){
    if(s.first > s.second) swap(s.first, s.second);
    mask += (1 << id[s]);
  }

  mask = decode(mask, 7);

  int n = 0;

  for(int i=0; i<28; i++) if(mask & (1 << i)) n += (1 << i);
  
  return n;

}

컴파일 시 표준 에러 (stderr) 메시지

cheat.cpp:1:40: warning: bad option '-f O3' to pragma 'optimize' [-Wpragmas]
    1 | #pragma GCC optimize("unroll-loops, O3")
      |                                        ^
In file included from cheat.cpp:4:
cheat.h:9:40: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
    9 | std::vector<Segment> BuildPattern(int n);
      |                                        ^
cheat.h:9:40: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
cheat.h:10:41: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
   10 | int GetCardNumber(std::vector<Segment> p);
      |                                         ^
cheat.h:10:41: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
cheat.cpp:20:21: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
   20 | void print(segment s){
      |                     ^
cheat.cpp:24:21: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
   24 | segment to_seg(int x){
      |                     ^
cheat.cpp:28:21: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
   28 | point rotate(point p){
      |                     ^
cheat.cpp:32:25: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
   32 | segment rotate(segment s){
      |                         ^
cheat.cpp:41:20: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
   41 | int rotate(int mask){
      |                    ^
cheat.cpp:56:50: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
   56 | void add(segment s, vector<vector<segment>> &segs){
      |                                                  ^
cheat.cpp:67:33: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
   67 | void add(int s, vector<int> &rot){
      |                                 ^
cheat.cpp:76:11: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
   76 | void init(){
      |           ^
cheat.cpp:107:26: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
  107 | int encode(int n, int pos){
      |                          ^
cheat.cpp:134:29: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
  134 | int decode(int mask, int pos){
      |                             ^
cheat.cpp:174:35: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
  174 | vector<segment> BuildPattern(int n){
      |                                   ^
cheat.cpp:193:36: warning: bad option '-f O3' to attribute 'optimize' [-Wattributes]
  193 | int GetCardNumber(vector<segment> p){
      |                                    ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...