해당 지점이 아니라 점과 점 사이의 경로의 방문 여부를 체크해줘야 한다. 처음 걸어본 길의 길이를 구해야 하므로 중복을 허락하지 않는 set
자료구조를 사용하였다.
그리고 방향성이 없으므로 (a, b)
에서 (b, a)
로 이동하는 것과 (b, a)
에서 (a, b)
로 이동하는 것은 같은 경우로 처리해줘야 한다!
#include <string>
#include <set>
#define MAX 10
using namespace std;
// directions
int dr[4] = { -1, 1, 0, 0 }; // U D R L
int dc[4] = { 0, 0, 1, -1 }; // U D R L
constexpr int UP = 0;
constexpr int DOWN = 1;
constexpr int RIGHT = 2;
constexpr int LEFT = 3;
bool check[4][MAX + 1][MAX + 1]; // (direction, nowR, nowC)
bool inMap(int r, int c) {
if (0 <= r && r <= MAX && 0 <= c && c <= MAX) return true;
else return false;
}
int solution(string dirs) {
int answer = 0;
int nowR = 5, nowC = 5;
int nextR, nextC, direction;
for (char ch : dirs) {
switch (ch) {
case 'U':
direction = UP;
break;
case 'D':
direction = DOWN;
break;
case 'R':
direction = RIGHT;
break;
case 'L':
direction = LEFT;
break;
default:
break;
}
nextR = nowR + dr[direction];
nextC = nowC + dc[direction];
if (inMap(nextR, nextC)) {
if (!check[direction][nowR][nowC]) {
answer++;
check[direction][nowR][nowC] = true;
switch (direction) {
case UP:
check[DOWN][nextR][nextC] = true;
break;
case DOWN:
check[UP][nextR][nextC] = true;
break;
case RIGHT:
check[LEFT][nextR][nextC] = true;
break;
case LEFT:
check[RIGHT][nextR][nextC] = true;
break;
}
}
nowR = nextR;
nowC = nextC;
}
}
return answer;
}
int dir2int(char ch) {
switch (ch) {
case 'U': return UP;
case 'D': return DOWN;
case 'R': return RIGHT;
case 'L': return LEFT;
default: return -1;
}
}
int solution2(string dirs) {
int answer;
int nowR = 5, nowC = 5;
int nextR, nextC, direction;
set< pair<int, int> > s;
for (char ch : dirs) {
direction = dir2int(ch);
nextR = nowR + dr[direction];
nextC = nowC + dc[direction];
if (inMap(nextR, nextC)) {
int now = 10 * nowR + nowC;
int next = 10 * nextR + nextC;
if (s.find({ now, next }) == s.end() && s.find({ next, now }) == s.end()) s.insert({ now, next });
nowR = nextR;
nowC = nextC;
}
}
return (int)s.size();
}