[백준] 로봇 시뮬레이션

유승선 ·2022년 9월 19일
0

백준

목록 보기
51/64

오랜만에 백준으로 넘어와서 문제를 고르고 풀어보았다. 구현 문제를 풀었는데 스트레스 받으면서 문제를 좀 빡쎄게 풀었다. 사실 구현 문제에 이제 꽤 자신이 있었지만 문제를 읽으면서 좀 스트레스 받을만한 설명이랑 조금 까다롭다고 생각했던 구현때문에 복잡하게 생각하느라 몇번씩 때려치울까 생각 했었다.

일반적인 Matrix 랑은 다르게 x 좌표가 왼쪽부터 가로 형태로 있었고 y 좌표가 밑에서부터 위로 있었다. 그래서 로봇을 배치하는 과정에서 좌표를 수정해야 할까 생각해 시간을 많이 잡아먹었다.

두번째로, 로봇이 움직이는 과정에서 다른 로봇과 겹치게 되면은 robot crash 로 끝나는게 아니고 어떤 로봇이랑 충돌 했는지도 기억하고 출력 했어야했다. 이때 Map 같은걸 써야하나 고민도 했지만 이내 구현이 말도 안되서 머리 속에 생각을 몇번씩 뒤집어서 엎었다.

결과적으로 문제 해결 방법은 좌표를 수정하는것이 아닌 그냥 좌표 그대로 가지고 와서 정말 말하는대로 수정 하면 됐었다. 말로는 쉬워보였지만 막상 구현해보니 꽤 많은 양의 줄을 썼고 고민도 좀 했었다.

일단 다음부터 이런 유형의 문제를 풀때 주의할점으로 방향 설정을 할때 더 신중히 해야겠다 생각했다. 이 문제는 x 좌표와 y좌표가 가로 세로 형태이기때문에 dir 방향도 일반적인게 아니고 바꿔주었고 방향을 바꾸는 과정도 신경써주었다.

#include <iostream> 
#include <bits/stdc++.h> 
#define endl "\n"
#define MAX 100010
using namespace std;

int A,B,N,M; //가로, 세로, 로봇 숫자, 명령 숫자 
int matrix[101][101];  
vector<pair<int,int>> dir = {{1,0},{-1,0},{0,-1},{0,1}}; //x 좌표 y좌표 바뀌어야한다 

struct Robot{
    int x, y;
    char direction; 
};

struct Command{
    int robotNum; 
    char command; 
    int repeat; 
};

vector<Robot> robotVec; 
vector<Command> commandVec; 

void Input(){
    cin >> A >> B >> N >> M; 
    int cnt = 1; 
    for(int i = 0; i < N; i++){
        int x, y; 
        char d; 
        cin >> x >> y >> d; 
        matrix[x][y] = cnt++; 
        robotVec.push_back({x,y,d}); 
    }
    for(int j = 0; j < M; j++){
        int x, r; 
        char d; 
        cin >> x >> d >> r; 
        commandVec.push_back({x,d,r}); 
    }
}

int findDir(Robot& robot){
    int curr_dir = -1; 
    if(robot.direction == 'E') curr_dir = 0; 
    if(robot.direction == 'W') curr_dir = 1; 
    if(robot.direction == 'S') curr_dir = 2; 
    if(robot.direction == 'N') curr_dir = 3; 
    return curr_dir; 
}

int changeLeft(int curr_dir){
    //cout << curr_dir << endl; 
    int ret = -1; 
    if(curr_dir == 0) ret = 3; 
    if(curr_dir == 1) ret = 2; 
    if(curr_dir == 2) ret = 0; 
    if(curr_dir == 3) ret = 1; 

    return ret; 
}

int changeRight(int curr_dir){
    int ret = -1; 
    if(curr_dir == 0) ret = 2;
    if(curr_dir == 1) ret = 3; 
    if(curr_dir == 2) ret = 1; 
    if(curr_dir == 3) ret = 0; 

    return ret; 
}

char convert(int curr_dir){
    char ret = 'E'; 
    if(curr_dir == 0) ret = 'E'; 
    if(curr_dir == 1) ret = 'W'; 
    if(curr_dir == 2) ret = 'S';
    if(curr_dir == 3) ret = 'N';
    return ret; 
}

string simulate(int robotNum, char command, int size){
    int index = robotNum -1; 
    Robot robot = robotVec[index]; 
    int curr_dir = findDir(robot); 
    int x = robot.x, y = robot.y;
    if(command == 'F'){
        for(int i = 0; i < size; i++){ //size 만큼 반복
            x += dir[curr_dir].first;
            y += dir[curr_dir].second; 
            if(x <= 0 || x > A || y <= 0 || y > B){
                return "Robot " + to_string(robotNum) + " crashes into the wall"; 
            }

            if(matrix[x][y] != 0){
                return "Robot " + to_string(robotNum) + " crashes into robot " + to_string(matrix[x][y]); 
            }
        }
        matrix[robot.x][robot.y] = 0; 
        matrix[x][y] = robotNum; 
        robotVec[index].x = x;
        robotVec[index].y = y; 
    }

    if(command == 'L'){
        int turn = size % 4; 
        for(int i = 0; i < turn; i++){
            curr_dir = changeLeft(curr_dir); 
        }
        robotVec[index].direction = convert(curr_dir); 
    }

    if(command == 'R'){
        int turn = size % 4; 
        for(int i = 0; i < turn; i++){
            curr_dir = changeRight(curr_dir); 
        }
        robotVec[index].direction = convert(curr_dir); 
    }



    return "OK"; 
}

void Solution(){
    string answer = "OK"; 
    for(int i = 0; i < commandVec.size(); i++){
        answer = simulate(commandVec[i].robotNum, commandVec[i].command, commandVec[i].repeat); 
        if(answer != "OK"){
            cout << answer;
            return; 
        }
    }
    cout << answer; 
}


void Solve(){
    Input();
    Solution(); 
}

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("input.txt", "r", stdin);
    Solve();
    return 0;

}

배운점:

  1. 방향 설정의 중요성
  2. 구현 할때 침착하자

TMI로 가볍게 시작했던 백준 문제들이었지만 골드 문제들만 골라서 많이 풀다보니깐 랭크가 올라서 기분이 좋았다.

profile
성장하는 사람

0개의 댓글