제출 #1325998

#제출 시각아이디문제언어결과실행 시간메모리
1325998SonicMLAliens (IOI07_aliens)C++20
0 / 100
1 ms332 KiB
#include <iostream>

using namespace std;

typedef long long ll;

int dirX[4] = {-1, 0, 1, 0};
int dirY[4] = {0, -1, 0, 1};

int borderDir[4];

struct Point{
  ll x;
  ll y;
};

int n;

bool isValid(Point pos) {
  return (1 <= pos.x && pos.x <= n && 1 <= pos.y && pos.y <= n);
}

bool examineColor(Point pos) {
  cout << "examine " << pos.x << ' ' << pos.y << endl;
  string answer;
  cin >> answer;
  if(answer == "true") {
    return true;
  }
  return false;
}

bool isInside(Point pos, Point red, Point white) {
  ll minX = min(red.x, white.x);
  ll maxX = max(red.x, white.x);
  ll minY = min(red.y, white.y);
  ll maxY = max(red.y, white.y);
  if(minX <= pos.x && pos.x <= maxX && minY <= pos.y && pos.y <= maxY) {
    return true;
  }
  return false;
}

int computeBorder(Point start, int dir) {
  Point lastRed = start;
  Point foundWhite = {0, 0};
  ll tempLimit = n+1;
  if(dir == 0 || dir == 1) {
    tempLimit = 0;
  }  
  for(int i = 0;i <= 31 && foundWhite.x == 0;i++) {
    ll moveX = dirX[dir] * (1LL<<i);
    ll moveY = dirY[dir] * (1LL<<i);
    Point pos = {lastRed.x + moveX, lastRed.y + moveY};
    if(isValid(pos)) {
      if(examineColor(pos) == true) {
        lastRed = pos;
      } else {
        foundWhite = pos;
      }
    }else {
      if(dir == 0 || dir == 2) {
        foundWhite = {tempLimit, lastRed.y};
      }else {
        foundWhite = {lastRed.x, tempLimit};
      }
    }
  } 
  foundWhite = {foundWhite.x - dirX[dir], foundWhite.y - dirY[dir]};
  for(int i = 31;i >= 0;i--) {
    ll moveX = dirX[dir] * (1LL<<i); 
    ll moveY = dirY[dir] * (1LL<<i);
    Point pos = {lastRed.x + moveX, lastRed.y + moveY};
    if(isValid(pos) && isInside(pos, lastRed, foundWhite)) {
      if(examineColor(pos) == true) {
        lastRed = pos;
      }
    }
  }
  return abs(lastRed.x - start.x) + abs(lastRed.y - start.y);
}

int main() {

  Point start;
  cin >> n >> start.x >> start.y;
  for(int dir = 0;dir < 4;dir++) {
    borderDir[dir] = computeBorder(start, dir);
    //cerr << dir << " : " << borderDir[dir] << '\n';
  }
  int m = borderDir[0] + 1 + borderDir[2];
  Point corner = {start.x-borderDir[0], start.y-borderDir[1]};
  Point realCorner = {0, 0};
  //cerr << corner.x << ' ' << corner.y << '\n';
  for(int i = 1;i <= 5;i++) {
    for(int j = 1;j <= 5;j++) {
      if((i + j) % 2 == 0) {
        int distX = (5-i)*m;
        int distY = (5-j)*m;
        Point newCorner = {corner.x-distX, corner.y-distY};
        if(isValid(newCorner)) {
          if(examineColor(newCorner)) {
            realCorner = newCorner;
          }
        }
      }
    }
  }   
  int jumpX = 2 * m + m/2;
  int jumpY = 2 * m + m/2;
  cout << "solution " << realCorner.x + jumpX << ' ' << realCorner.y + jumpY << endl;  
  return 0;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...