Submission #405464

#TimeUsernameProblemLanguageResultExecution timeMemory
405464ollelTriangles (CEOI18_tri)C++14
35 / 100
368 ms2500 KiB
#include <bits/stdc++.h>
#include <iostream>
#include "trilib.h"
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef tuple<int,int,int> tiii;

#define rep(i,a,b) for(int i = a; i < b; i++)
#define pb push_back

int n, guesses = 999995;

map<tiii, bool> cw;
//
// bool is_clockwise(int a, int b, int c) {
//   cout << "clockwise? " << a << " " << b << " " << c << endl;
//   bool ans;
//   cin >> ans;
//   return ans;
// }
//
// int get_n(){
//   int N; cin >> N; return N;
// }

bool clockwise(int a, int b, int c){
  tiii t = make_tuple(a, b, c);
  if (cw.find(t) != cw.end()) return cw[t];
  guesses--;
  bool ans = is_clockwise(a, b, c);
  cw[{a, b, c}] = cw[{b, c, a}] = cw[{c, a, b}] = ans;
  cw[{a, c, b}] = cw[{c, b, a}] = cw[{b, a, c}] = !ans;
  return ans;
}

int getleft(int a, set<int>& s) {
  int b = *s.begin();

  for (auto & c : s) {
    if (c == b) continue;
    if (clockwise(a, b, c)) b = c;
  }

  return b;
}

int getright(int a, set<int>& s) {
  int b = *s.begin();

  for (auto & c : s) {
    if (c == b) continue;
    if (!clockwise(a, b, c)) b = c;
  }

  return b;
}

pair<int,int> first_hull() {
  int a = 1, b = 2;
  // assume a top

  set<int> left, right;
  rep(i, 3, n + 1) {
    if (clockwise(a, b, i)) left.insert(i);
    else right.insert(i);
  }

  if (left.empty() || right.empty()) return make_pair(a, b);

  int l = getleft(a, left);
  int r = getright(a, right);
  if (clockwise(l, r, a)) return make_pair(l, r);
  else return {l, a};
}

vi sort_hull(int sortby) {
  vi s = {(sortby == 1) ? 2:1};

  rep(i, 1, n + 1) {
    if (i == sortby || i == s[0]) continue;
    int low = 0, high = s.size(), mid;
    while (high - low > 1) {
      mid = (high + low) / 2;
      if (clockwise(sortby, i, s[mid])) high = mid;
      else low = mid;
    }

    if (clockwise(sortby, i, s[low])) s.insert(s.begin() + low, i);
    else s.insert(s.begin() + low + 1, i);
  }

  s.insert(s.begin(), sortby);
  return s;
}

int main()
{
  n = get_n();
  pair<int,int> p = first_hull();
  int sortby = p.first;
  vi s = sort_hull(sortby);
  int ans = n;
  vi nxt(n+1);
  rep(i,0,n-1) nxt[s[i]] = s[i + 1];
  nxt[s[n - 1]] = s[0];

  int cur = 1, l = 1e6;
  while (guesses && l) {
    l--;

    if (!clockwise(cur, nxt[cur], nxt[nxt[cur]])) {
      ans--;
      nxt[cur] = nxt[nxt[cur]];
    }
    cur = nxt[cur];
  }

  cout << ans << endl;
}
#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...