문제 링크

요약

  • 그냥 좌표를 하나하나 따라가는게 더 나을 수도 있다.

최종

  • 여기 에서는 움직이는 범위를 이용해 이 안에 obstacle 이 있나 찾는 방법으로 접근했는데, 해보니 통과되긴 하지만 너무 느리다.
  • 그래서 다른사람 solution 을 보니 그냥 좌표를 1씩 움직이길래 그렇게하는게 더 빠른가 싶어서 해봤더니 확실히 더 낫긴 하다.
  • 코드는:
#define PACK(x, y) (((x) << 16) | ((y) & 0xFFFF))
#define EUCLID(pos) ((pos)[0] * (pos)[0] + (pos)[1] * (pos)[1])
#define MAX(a, b) ((a) > (b) ? (a) : (b))
 
#define DIR_UP      (0)
#define DIR_RIGHT   (1)
#define DIR_DOWN    (2)
#define DIR_LEFT    (3)
 
class Solution {
private:
	static constexpr int direction_map[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
 
	int pos[2];
	int direction;
	int max_distance;
	set<int> obstacles;
 
	void init(vector<vector<int>> &obstacles) {
		pos[0] = 0;
		pos[1] = 0;
		direction = DIR_UP;
		max_distance = 0;
		
		for (auto &o : obstacles) {
			this->obstacles.insert(PACK(o[0], o[1]));
		}
	}
 
	void turnRight() {
		direction = (direction + 1) & 0x3;
	}
 
	void turnLeft() {
		direction = (direction - 1) & 0x3;
	}
 
	void move(int distance) {
		for (int i = 0; i < distance; i++) {
			int next[2];
 
			next[0] = pos[0] + direction_map[direction][0];
			next[1] = pos[1] + direction_map[direction][1];
 
			if (obstacles.find(PACK(next[0], next[1])) != obstacles.end()) {
				break;
			}
 
			pos[0] = next[0];
			pos[1] = next[1];
		}
 
		max_distance = MAX(max_distance, EUCLID(pos));
	}
 
	void act(int command) {
		switch (command) {
		case -2: turnLeft(); break;
		case -1: turnRight(); break;
		default: move(command); break;
		}
	}
public:
	int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) {
		init(obstacles);
 
		for (auto c : commands) {
			act(c);
		}
 
		return max_distance;
	}
};

삽질 기록

  • 위에서 말한 그 느린 코드.