답안 #438266

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
438266 2021-06-27T19:53:43 Z CyanForces 레지스터 (IOI21_registers) C++17
10 / 100
2 ms 460 KB
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#include "registers.h"

int s, n, k, q;
int ops = 0;
vector<bool> negOne(2000);
vector<bool> signBit(2000);
vector<bool> oneNum(2000);


const int negOneIndex = 99;
const int signBitIndex = 98;
const int oneNumIndex = 97;
const int workRegister = 96;

int bit_len;

void spread() {
  append_print(0);
  vector<bool> takeFirst(2000), takeSecond(2000);
  rep(i,0,2000) {
    int temp = (i / (k)) % 2;
    if (temp == 0) takeFirst[i] = 1;
    else takeSecond[i] = 1;
  }
  append_store(50, takeFirst);
  ops++;
  append_store(51, takeSecond);


  append_and(1, 0, 50);
  append_and(0, 0, 51);

  append_print(0);
  append_print(1);

  append_left(0, 0, (n-1)*k);
  append_xor(1,0,1);

  //for(int i = 0; i < n; i++) {
  //  append_and(workRegister, 0, oneNumIndex);
  //  ops++;
  //  if (i != n-1) {
  //    append_left(oneNumIndex, oneNumIndex, bit_len);
  //    ops++;
  //    append_left(0, 0, k);
  //    ops++;
  //  }
  //  append_or(1, 1, workRegister);
  //  ops++;
  //}
}

void divide() {
  int leftNumbers = (n+1) / 2;
  //append_move(2, 1);
  ops++;
  append_right(2, 1, leftNumbers * (bit_len));
  ops++;
  if(n % 2 == 1) {
    vector<bool> tempExtra(2000);
    rep(i,0,2000) {
      tempExtra[i] = (n-leftNumbers)*(bit_len) <= i && i < (n-leftNumbers+1)*(bit_len)-1;
    }
    append_store(3, tempExtra);
    ops++;
    append_or(2, 2, 3);
    ops++;
  }
}

void spreadSigns(int d) {
  ops++;
  append_right(workRegister, 0, d);
  ops++;
  append_or(0, 0, workRegister);
  ops++;
}

void combine() {
  ops++;
  append_add(0, negOneIndex, 2); // b-1
  ops++;
  append_not(0, 0); // !(b-1)
  ops++;
  append_add(0, 0, 1); // a-b
  ops++;

  append_and(0, 0, signBitIndex);
  ops++;
  //rep(_,0,k+1) spreadSigns(1);
  int curr = 1;
  while(curr*2 < bit_len) {
    spreadSigns(curr);
    curr *= 2;
  }
  if (bit_len != curr) spreadSigns(bit_len - curr);

  append_not(workRegister, 0);
  ops++;
  // registry 0 contains zeros if a >= b, else 1
  // => registry 0 contains a >= b
  // => workRegister contains a < b
  append_and(0, 0, 2);
  ops++;
  append_and(workRegister, workRegister, 1);
  ops++;

  //append_xor(1, 1, 2);
  // register 0 = xor(a, b)
  ops++;
  append_xor(1, 0, workRegister);
  ops++;
  // register 2 = max(a, b)
  //append_xor(1, 1, 2);
  ops++;
}

void print() {
  rep(i,0,3) append_print(i);
}

void findMin() {
  spread();
  //return;
  while(n > 1) {
    //print();
    divide();
    //print();
    combine();
    //print();
    n = (n+1) / 2;
  }
  //print();
  append_move(0, 1);
  ops++;
}

void unspread() {
  vector<bool> empty(2000);
  append_store(0, empty);
  int shiftAmount = n-1;

  for(int i = n-1; i >= 0; i--) {
    cerr << "i = " << i << endl;
    cerr << "ops = " << ops << endl;
    append_and(workRegister, 1, oneNumIndex);
    ops++;
    append_right(workRegister, workRegister, 2*i);
    ops++;
    append_right(oneNumIndex, oneNumIndex, bit_len);
    ops++;
    if (shiftAmount > 0) {
      append_right(workRegister, workRegister, shiftAmount * k);
    }
    else {
      append_left(workRegister, workRegister, -shiftAmount * k);
    }
    shiftAmount -= 2;

    append_or(0, 0, workRegister);
    ops++;
  }

  //append_store(oneNumIndex, oneNum);
  //append_store(1, empty);
  //spread();
  //print();
}

void stupidSort() {
  spread();

  vector<bool> tempExtra(2000);
  rep(i,0,2000) {
    tempExtra[i] = i < k;
  }
  append_store(75, tempExtra);
  ops++;

  vector<bool> takeFirst(2000), takeSecond(2000);
  rep(i,0,2000) {
    int temp = (i / (bit_len)) % 2;
    if (temp == 0) takeFirst[i] = 1;
    else takeSecond[i] = 1;
  }
  append_store(50, takeFirst);
  ops++;
  append_store(51, takeSecond);
  ops++;
  cerr << "n = " << n << endl;
  print();
  rep(i,0,n+3) {
    print();
    cerr << "i = " << i << ", ops = " << ops << endl;
    append_move(2, 1);
    ops++;
    append_left(2, 2, bit_len);
    ops++;
    append_xor(2, 2, 75);
    ops++;
    combine();
    print();

    cerr << "i = " << i << ", ops = " << ops << endl;
    if (i % 2 == 0) {
      append_and(1, 1, 50);
      ops++;
      append_and(2, 2, 50);
      ops++;
      append_right(2, 2, bit_len);
      ops++;
    }
    else {
      append_and(1, 1, 51);
      ops++;
      append_and(2, 2, 51);
      ops++;
      append_right(2, 2, bit_len);
      ops++;
    }
    print();
    append_or(1, 1, 2);
    ops++;
    append_print(52);
  }

  unspread();
}

void construct_instructions(int _s, int _n, int _k, int _q) {
  s = _s;
  n = _n;
  k = _k;
  q = _q;
  bit_len = 2*k;
  int a = 0;
  int b = bit_len;
  while(b < 2000) {
    for(int j = a; j < b; j++) negOne[j] = j != b-1;
    a = b;
    b += bit_len;
  }
  for(int i = 0; i < 2000; i++) {
    signBit[i] = i % (bit_len) == bit_len-1;
    oneNum[i] = i < k;
  }
  append_store(negOneIndex, negOne);
  ops++;
  append_store(signBitIndex, signBit);
  ops++;
  append_store(oneNumIndex, oneNum);
  ops++;

  if (s == 0) {
    findMin();
  }
  else {
    stupidSort();
  }
  assert(ops <= q);
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 204 KB Wrong answer detected in grader
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 204 KB Incorrect min value
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 460 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 2 ms 332 KB Incorrect sorting
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 2 ms 332 KB Incorrect sorting
2 Halted 0 ms 0 KB -