서론
아직까진 30분 안에 풀고 있으니 할만한데라고 생각하니, 이게 웬걸 상당히 오래 걸리는 문제를 2주차 막바지에 만나버렸다.
문제 이해를 못한것도 충격이었고, 중간에 발생한 문제도 문자열에 관한 기본적인 문제여서 발전이 필요하구나 라는 생각을 들게 하였다.
5일차 GameJam
문제 요약 : 맵의 각 위치에는 이동해야 되는 명령어가 있고 이를 따라 이동하되, 한번 방문한 곳을 다시 갔을경우 종료된다.
플레이어와 구름이 게임을 하며 점수는 각각 방문한 위치의 수이다.
이긴 사람의 이름과 점수를 출력하시오.
어려웠던 점
●문제해석
문제를 읽다가 입력부분에 이해가 되지 않는 부분이 있었다.
'i번째 줄에서 j번째로 주어지는 지시 사항은 보드의 r번째 행, c번째 열의 정보를 의미한다'?
나는 command라는 변수명을 보고 N개의 줄에 제공되는 것들은 게임을 진행하며 사용하는 명령어로 착각하여서 왜 행열의 정보를 제공하지라는 생각을 하였는데,
사실 이것은 맵에 써져있는 커맨드였었다.
이걸 혼자 알게된것이 아니라 같이 구름톤을 진행하는 친구에게 물어보고 나서 알게 된 후 정신 바짝 차리고 독해를 해야겠다는 생각을 하였다.
●인덱싱
처음 코드를 작성할때, 명령어가 command = "5D"면 인덱싱을 통해서 command[0]와 command[1]을 통해 분리하면 되겠다는 생각을 했는데, 이는 잘못된 생각이었다.
왜냐하면 앞의 숫자가 2자리가 넘어갈 수 도 있기 때문이다.
N은 보드판의 크기이고, R과 C는 이동 거리(count)이다.
따라서 위의 조건에서는 최대 이동 거리(count)는 200이 된다.
그래서 이동거리는 뒤에 한 문자를 제외하고 문자를 숫자로 바꾸어 처리하고,
이동방향은 뒤에 한문자를 통해 처리하였다.
char dir = map[loc.first][loc.second][map[loc.first][loc.second].size() - 1];
int count = stoi(map[loc.first][loc.second].substr(0, map[loc.first][loc.second].size() - 1));
배운 점
문자열 입력을 받아 이를 처리하는 것이 필요했는데 필요한 split() 함수를 작성하는 법이 생각나지 않아서 이를 보고 작성하였는데, 한 번 더 머리에 되새기는 경험을 하게 되었다.
또한 어려웠던 점들을 해결하면서 문제를 분석하는 능력과 이를 해결하는 법을 숙달할 수 있었다.
느낀 점
간단한 구현문제인데도 이렇게 애를 쓴걸 보니 기초가 아직 부족함을 실감할 수 있었다.
또한 리펙토링을 하면서 코드의 길이가 절반이 되는 것을 확인하고, 가독성 좋고 짧은 코드를 지향하는 것에 기분 좋음을 느낄 수 있었다.
◆코드 전문◆
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> split(string input, string delimeter);
bool command(const vector<vector<string>> &map,
vector<vector<int>> &pointMap,
pair<int, int> &loc);
int main()
{
int N;
int groomPoint = 0, playerPoint = 0;
pair<int, int> groom, player;
cin >> N;
cin >> groom.first >> groom.second;
cin >> player.first >> player.second;
groom.first--, groom.second--, player.first--, player.second--;
cin.get();
vector<vector<string>> map(N);
vector<vector<int>> groomPointMap(N, vector<int>(N));
vector<vector<int>> playerPointMap(N, vector<int>(N));
groomPointMap[groom.first][groom.second] = 1;
playerPointMap[player.first][player.second] = 1;
string str;
for (int i = 0; i < N; i++)
{
string str = "";
getline(cin, str);
map[i] = split(str, " ");
}
while (command(map, groomPointMap, groom)){}
while (command(map, playerPointMap, player)){}
for (int i = 0; i < N; i++)
{
for (int k = 0; k < N; k++)
{
groomPoint += groomPointMap[i][k];
playerPoint += playerPointMap[i][k];
}
}
if (groomPoint > playerPoint)
{
cout << "goorm " << groomPoint;
}
else
{
cout << "player " << playerPoint;
}
return 0;
}
vector<string> split(string input, string delimeter)
{
vector<string> ret;
long long pos = 0;
string token = "";
while ((pos = input.find(delimeter)) != string::npos)
{
token = input.substr(0, pos);
ret.push_back(token);
input.erase(0, pos + delimeter.length());
}
ret.push_back(input);
return ret;
}
bool command(const vector<vector<string>> &map,
vector<vector<int>> &pointMap,
pair<int, int> &loc)
{
char dir = map[loc.first][loc.second][map[loc.first][loc.second].size() - 1];
int count = stoi(map[loc.first][loc.second].substr(0, map[loc.first][loc.second].size() - 1));
for (int i = 0; i < count; i++)
{
switch (dir)
{
case 'U':
loc.first += -1;
if (loc.first < 0)
loc.first = map.size() - 1;
break;
case 'D':
loc.first += 1;
if (loc.first >= map.size())
loc.first = 0;
break;
case 'R':
loc.second += 1;
if (loc.second >= map.size())
loc.second = 0;
break;
case 'L':
loc.second += -1;
if (loc.second < 0)
loc.second = map.size() - 1;
break;
default:
break;
}
if (pointMap[loc.first][loc.second] == 1)
{
return false;
}
pointMap[loc.first][loc.second] = 1;
}
return true;
}
'코딩 공부 > TIL(Today I Learn)' 카테고리의 다른 글
구름톤 챌린지 3주차 학습 일기(2) 맞왜틀? (0) | 2023.08.29 |
---|---|
구름톤 챌린지 3주차 학습 일기(1) 맞왜틀? (0) | 2023.08.29 |
구름톤 챌린지 2주차 학습 일기(1) (0) | 2023.08.21 |
구름톤 챌린지 1주차 학습 일기(2) (0) | 2023.08.19 |
[빠른 C++][백준 15552] 빠른 A+B (0) | 2023.07.15 |