Submission #102632

#TimeUsernameProblemLanguageResultExecution timeMemory
102632wxh010910Scales (IOI15_scales)C++17
100 / 100
334 ms16816 KiB
#include <bits/stdc++.h>
#include "scales.h"

using namespace std;

const int N = 6;
const int M = 720;
const int S = 5184;
const vector<int> p3 = {1, 3, 9, 27, 81, 243, 729};

vector<vector<int>> value(M, vector<int>(S, -1));
map<pair<vector<int>, int>, int> tree;
vector<vector<int>> all(M);
vector<bool> valid(S);
vector<int> choices;

bool dfs(vector<int> remain, int depth) {
  if ((int) remain.size() > p3[depth]) {
    return false;
  }
  if ((int) remain.size() == 1) {
    return true;
  }
  if (tree.count(make_pair(remain, depth))) {
    return tree[make_pair(remain, depth)] != -1;
  }
  for (auto p : choices) {
    vector<vector<int>> partition(N);
    for (auto i : remain) {
      partition[value[i][p]].push_back(i);
    }
    bool ok = true;
    for (int i = 0; i < N; ++i) {
      if (!partition[i].empty() && !dfs(partition[i], depth - 1)) {
        ok = false;
        break;
      }
    }
    if (ok) {
      tree[make_pair(remain, depth)] = p;
      return true;
    }
  }
  tree[make_pair(remain, depth)] = -1;
  return false;
}

void go(vector<int> remain, int depth) {
  if ((int) remain.size() == 1) {
    int* ans = new int[N];
    for (int i = 0; i < N; ++i) {
      ans[all[remain[0]][i]] = i + 1;
    }
    answer(ans);
    return;
  }
  int code = tree[make_pair(remain, depth)];
  int type = code / 1296;
  int a = code / 216 % 6;
  int b = code / 36 % 6;
  int c = code / 6 % 6;
  int d = code % 6;
  int res;
  if (type == 0) {
    res = getHeaviest(a + 1, b + 1, c + 1) - 1;
  } else if (type == 1) {
    res = getLightest(a + 1, b + 1, c + 1) - 1;
  } else if (type == 2) {
    res = getMedian(a + 1, b + 1, c + 1) - 1;
  } else {
    res = getNextLightest(a + 1, b + 1, c + 1, d + 1) - 1;
  }
  vector<int> new_remain;
  for (auto i : remain) {
    if (value[i][code] == res) {
      new_remain.push_back(i);
    }
  }
  go(new_remain, depth - 1);
}

void init(int T) {
  vector<int> p(N);
  for (int i = 0; i < N; ++i) {
    p[i] = i;
  }
  for (int i = 0; i < 3; ++i) {
    for (int a = 0; a < N; ++a) {
      for (int b = a + 1; b < N; ++b) {
        for (int c = b + 1; c < N; ++c) {
          valid[i * 1296 + a * 216 + b * 36 + c * 6 + 0] = true;
        }
      }
    }
  }
  for (int a = 0; a < N; ++a) {
    for (int b = a + 1; b < N; ++b) {
      for (int c = b + 1; c < N; ++c) {
        for (int d = 0; d < N; ++d) {
          if (d == a || d == b || d == c) {
            continue;
          }
          valid[3 * 1296 + a * 216 + b * 36 + c * 6 + d] = true;
        }
      }
    }
  }
  for (int i = 0; i < S; ++i) {
    if (valid[i]) {
      choices.push_back(i);
    }
  }
  for (int ptr = 0; ptr < M; ++ptr) {
    all[ptr] = p;
    for (int a = 0; a < N; ++a) {
      for (int b = a + 1; b < N; ++b) {
        for (int c = b + 1; c < N; ++c) {
          vector<int> seq = {a, b, c};
          sort(seq.begin(), seq.end(), [&](const int &x, const int &y) {
            return p[x] < p[y];
          });
          value[ptr][0 * 1296 + a * 216 + b * 36 + c * 6 + 0] = seq[2];
          value[ptr][1 * 1296 + a * 216 + b * 36 + c * 6 + 0] = seq[0];
          value[ptr][2 * 1296 + a * 216 + b * 36 + c * 6 + 0] = seq[1];
          for (int d = 0; d < N; ++d) {
            if (d == a || d == b || d == c) {
              continue;
            }
            if (p[d] > p[seq[2]]) {
              value[ptr][3 * 1296 + a * 216 + b * 36 + c * 6 + d] = seq[0];
            } else {
              for (int i = 0; i < 3; ++i) {
                if (p[seq[i]] > p[d]) {
                  value[ptr][3 * 1296 + a * 216 + b * 36 + c * 6 + d] = seq[i];
                  break;
                }
              }
            }
          }
        }
      }
    }
    next_permutation(p.begin(), p.end());
  }
  vector<int> remain(M);
  for (int i = 0; i < M; ++i) {
    remain[i] = i;
  }
  dfs(remain, 6);
}

void orderCoins() {
  vector<int> remain(M);
  for (int i = 0; i < M; ++i) {
    remain[i] = i;
  }
  go(remain, 6);
}

Compilation message (stderr)

In file included from grader.c:2:0:
graderlib.c: In function 'void answer(int*)':
graderlib.c:53:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
     if (_ghksjhdfkae19ga_ > 1) 
     ^~
graderlib.c:56:2: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
  for (i = 0; i < 6; i++) {
  ^~~
scales.cpp: In function 'void init(int)':
scales.cpp:82:15: warning: unused parameter 'T' [-Wunused-parameter]
 void init(int T) {
               ^
#Verdict Execution timeMemoryGrader output
Fetching results...