https://school.programmers.co.kr/learn/courses/30/lessons/172928
위 그리드는 공원! 나는 동서남북 방향으로 주어진 칸 수만큼 움직이며 로봇 강아지!
park - 공원을 나타내는 vector<string> - ["SOO", "OOX", "OOO"] - S 는 시작, O는 이동 가능, X는 이동 불가
routes - 이동 명령이 담긴 vector<string> - "E 2" 동쪽으로 2칸, "N 3" 북쪽으로 3칸 등
아주 literal 한 나의 풀이
routes 에서 주어진 string 의 첫번째와 세번째 글자를 변수에 저장하고,
switch 문을 활용해 현재 위치에서 동/서/남/북 방향 (첫번째 변수) 으로 몇칸 (두번째 변수) 이동할 때
1. 범위를 넘어가지 않는지 / 2. 경로에 X 가 없는지
확인하여 두 조건을 모두 충족하면 현재 위치를 해당 방향으로 칸 수만큼 이동시키는 코드를 작성하여 제출했다.
당연히 (문제에서 제시된 프로세스를 word to word 그대로 구현했으므로...) 문제 없이 넘어가지만, 장황한 풀이가 되어버렸다.
//...inside loop iterating routes
char op = routes[i][0];
int n = routes[i][2] - '0';
switch (op)
{
case 'E':
if (CurrCol + n < Width)
{
bool FoundX = false;
for (int i = CurrCol; i <= CurrCol + n; i++)
{
if (park[CurrRow][i] == 'X')
{
FoundX = true;
break;
}
}
if (!FoundX) CurrCol += n;
}
break;
case 'W':
if (CurrCol - n >= 0)
{
bool FoundX = false;
for (int i = CurrCol; i >= CurrCol - n; i--)
{
if (park[CurrRow][i] == 'X')
{
FoundX = true;
break;
}
}
if (!FoundX) CurrCol -= n;
}
break;
case 'N':
if (CurrRow - n >= 0)
{
bool FoundX = false;
for (int i = CurrRow; i >= CurrRow - n; i--)
{
if (park[i][CurrCol] == 'X')
{
FoundX = true;
break;
}
}
if (!FoundX) CurrRow -= n;
}
break;
case 'S':
if (CurrRow + n < Height)
{
bool FoundX = false;
for (int i = CurrRow; i <= CurrRow + n; i++)
{
if (park[i][CurrCol] == 'X')
{
FoundX = true;
break;
}
}
if (!FoundX) CurrRow += n;
}
break;
}
//.....
특히 EWSN 각 케이스마다 아주 비슷한 프로세스를 수행하고 있기에, 더 나은 풀이가 없을까 고민해보았다.
EWSN 의 경우 각각의 방향이므로, 이를 unordered_map<char, int> 로 만들어 배열의 인덱스로 활용할 수 있다는 생각까지는 했지만, EW / SN 를 각각 column / row 로 구별해야 한다는 생각에 적당한 방법을 떠올리지 못했다.
그래서 다른 사람의 풀이를 참고하였다.
EWSN 각각 이동값을 배열로 사용 / map 으로 EWSN 을 인덱스화
1. EWSN 를 각각 0, 1, 2, 3 으로 map 하여 인덱스로 사용
--> unordered_map<char, int> opMap = { {‘E’, 0}, {‘W’, 1}, {‘S’, 2}, {‘N’, 3} };
2. EWSN 각각에 해당하는 델타 (이동) 값을 배열로 저장
--> int dRow[4] = {0, 0, 1, -1}; (EW 는 0, SN 은 +-1)
int dCol[4] = {1, -1, 0, 0}; (EW 는 +-1, SN 은 0)
그렇다, EW SN 각각 이동하지 않는 부분에 대해서는 0을 가져가게 하면 된다...!
이렇게 되면 routes 를 iterate 하며 현재 row 와 col 을 어느 방향으로, 얼만큼 이동시켜야 하는지에 상관 없이
배열에서 인덱스로 접근하여 바로 연산 가능하다.
//----inside the loop iterating routes
int n = routes[i][2] - '0'; // n = number of steps
int op = opMap[routes[i][0]]; // op = EWSN as an index
while (n--)
{
row += dRow[op];
col += dCol[op];
if (row or col is out of range) break;
if (park[row][col] == 'X') break;
}
if (n < 0)
{
currRow = row; currCol = col;
}
//----
n 이 계속 감소하며 0이 되었을 때 while loop 은 종료되고 n 은 마지막으로 1 감소하므로 n < 0 인 경우 break; 없이 while 을 빠져나왔으므로 이동 가능함을 알 수 있다.
코드카타를 하면서, '이러면 되겠다' 해서 코드를 작성하고, 테스트 케이스 통과하면 바로 제출 누르....기 전에!!!... 꼭 이 코드가 최선인지 고민하기로 (수십번째) 다짐을 한다...
'언리얼_엔진_게임개발_공부 > 알고리즘&자료구조' 카테고리의 다른 글
[코드카타] 완전탐색 - 피로도 - 백트래킹 vs. std::next_permutation (0) | 2025.04.28 |
---|---|
동적 계획법 / 다이나믹 프로그래밍 Dynamic Programming (0) | 2025.03.25 |
[코드카타] 재귀함수 / 꼬리 재귀 / 꼬리 호출 최적화 TCO (1) | 2025.01.22 |
[코드카타] "내 코드 쓰레기네" ... 과연 그럴까? (1) | 2025.01.17 |
[코드카타] 재귀함수로 문제 풀다가 실수한 것 정리 ㅠㅠ (0) | 2025.01.08 |