💡
문제가 요구하는 조건을 생각하고, 이를 함수로 쪼개서 구현하는 게 실수를 줄일 수 있는 방법인 듯
예를 들어, 문제에서 어떤 정렬 조건과 예외 처리 조건이 주어질 때, sort에 람다함수를 사용하는 것 대신 함수를 따로 만들어서 sort의 비교 함수로 넣으면 더 가독성이 좋음
#include <string>
#include <set>
using namespace std;
int solution(string dirs) {
int answer = 0;
int x = 0, y = 0;
set<pair<int, int>> positions;
for (int i = 0; i < dirs.length(); i++) {
if (dirs[i] == 'U' && y < 5) {
y++;
}
else if (dirs[i] == 'D' && y > -5) {
y--;
}
else if (dirs[i] == 'R' && x < 5) {
x++;
}
else if (dirs[i] == 'L' && x > -5) {
x--;
}
positions.insert({x, y});
}
return positions.size();
}
🤓 실수
int x, y = 0;
x,y 둘 다 0으로 초기화 하려면 x = 0, y = 0 이렇게 해야하는데 저렇게 해서 y만 초기화 됨dirs[i] == "U"
dirs[i]와 명령어를 비교할 때 char은 작은 따옴표를 사용해야 하는데 큰 따옴표를 사용해서 char와 const char*를 비교하는 꼴이 되어버림
💥 문제점
다른 길을 통해 다시 그 점에 돌아온 경우, 동일한 좌표이긴 하지만 다른 길이기 때문에 이 경우도 카운트를 해야 하는데 set을 써서 중복은 무조건 예외처리가 되어버림
#include <string>
#include <set>
using namespace std;
bool visited[11][11][4]; // 1. 특정 좌표에서 특정 방향으로 이동한 적이 있는지 체크
// 2. 상하좌우로 좌표를 이동할 때 필요한 좌표의 오프셋 배열
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
// 3. 각 문자에 해당하는 오프셋 배열의 인덱스를 반환
int todir(char dir) {
int ret;
if (dir == 'U')
ret = 0;
else if (dir = 'R')
ret = 1;
else if (dir = 'D')
ret = 2;
else
ret = 3;
return ret;
}
// 4. 특정 좌표가 주어진 좌표 평면을 벗어나는지 확인
bool isNotValid(int x, int y) { return x < 0 || y < 0 || x > 10 || y > 10; }
// 5. 현재와 반대 방향의 오프셋 배열 인덱스 반환
int opposite_direction(int dir) {return (dir + 2) % 4; }
int solution(string dirs) {
int answer = 0;
int x = 5, y = 5; // 6. 시작 좌표를 설정
for (auto c : dirs) {
// 7. 반복문을 순회하며 nx, ny는 x, y가 dirs대로 움직였을 때 위치가 됨
int dir = todir(c);
int nx = x + dx[dir];
int ny = y + dx[dir];
// 8. 좌표 평면을 벗어나면 더 이상 이동하지 않음
if (isNotValid(nx, ny))
continue;
// 9. 다음 좌표가 아직 방문하지 않은 좌표인 경우
if (visited[y][x][dir] == false) {
// 10. 방문을 중복 체크하지 않도록 해당 경로의 양방향 방문을 체크
visited[y][x][dir] = true;
visited[ny][nx][opposite_direction(dir)] = true;
answer++;
}
// 11. 현재 좌표를 이동한 좌표로 업데이트
x = nx;
y = ny;
}
return answer;
}
#include <string>
#include <set>
using namespace std;
bool visited[11][11][4]; // 좌표, 상하좌우 방향 저장 (x, y 좌표를 1부터 10까지 저장할 것이기 때문에 11개 할당)
int todir(char dir) {
if (dir == 'U') return 0;
else if (dir == 'R') return 1;
else if (dir == 'D') return 2;
else return 3;
}
int opposite_dir(int dir) {
return (dir + 2) % 4;
}
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
bool isNotValid(int x, int y) { return x < 0 || y < 0 || x > 10 || y > 10; }
int solution(string dirs) {
int answer = 0;
int x = 5, y = 5; // 시작 좌표 설정
for (auto c : dirs) {
int dir = todir(c); // 방향 인덱싱을 위해 dir을 int로 저장
// x, y 좌표를 dir방향 오프셋만큼 이동
int nx = x + dx[dir];
int ny = y + dy[dir];
// continue 하면 기존 x, y를 업데이트 하지 않기 때문에 이동 처리 되지 않음
if (isNotValid(nx, ny)) continue;
if (visited[y][x][dir] == false) {
visited[y][x][dir] = true; // 기존 좌표에서 다음 좌표로 가는 직선
visited[ny][nx][opposite_dir(dir)] = true; // 다음 좌표에서 기존 좌표로 오는 직선
answer++;
}
// 다음 좌표로 이동
x = nx;
y = ny;
}
return answer;
}
🤓 실수
int todir(char dir) { if (dir == 'U') return 0; else if (dir == 'D') return 1; else if (dir == 'R') return 2; else return 3; }dx, dy 배열은 [D(하), R(우), U(상), L(좌)] 순서로 되어있기 때문에 인덱스 리턴하는 것도 이 순서에 맞춰서 해야하는데 잘못된 방향 인덱스 리턴하게 구현해버림
근데 지금 보니까 책도 배열은 [D, R, U, L] 순서로 짜놓고 인덱싱 하는 건 [U, R, D, L] 순으로 했네,,,이게 올바른 풀이
int todir(char dir) { if (dir == 'D') return 0; else if (dir == 'R') return 1; else if (dir == 'U') return 2; else return 3; }