BOJ/시물레이션

[C/C++] 백준 - 2174번 : 로봇 시뮬레이션

JWonK 2022. 6. 4. 15:16
728x90
반응형

https://www.acmicpc.net/problem/2174

 

2174번: 로봇 시뮬레이션

첫째 줄에 두 정수 A, B가 주어진다. 다음 줄에는 두 정수 N, M이 주어진다. 다음 N개의 줄에는 각 로봇의 초기 위치(x, y좌표 순) 및 방향이 주어진다. 다음 M개의 줄에는 각 명령이 명령을 내리는 순

www.acmicpc.net

문제

가로 A(1≤A≤100), 세로 B(1≤B≤100) 크기의 땅이 있다. 이 땅 위에 로봇들이 N(1≤N≤100)개 있다.

로봇들의 초기 위치는 x좌표와 y좌표로 나타난다. 위의 그림에서 보듯 x좌표는 왼쪽부터, y좌표는 아래쪽부터 순서가 매겨진다. 또한 각 로봇은 맨 처음에 NWES 중 하나의 방향을 향해 서 있다. 초기에 서 있는 로봇들의 위치는 서로 다르다.

이러한 로봇들에 M(1≤M≤100)개의 명령을 내리려고 한다. 각각의 명령은 순차적으로 실행된다. 즉, 하나의 명령을 한 로봇에서 내렸으면, 그 명령이 완수될 때까지 그 로봇과 다른 모든 로봇에게 다른 명령을 내릴 수 없다. 각각의 로봇에 대해 수행하는 명령은 다음의 세 가지가 있다.

  1. L: 로봇이 향하고 있는 방향을 기준으로 왼쪽으로 90도 회전한다.
  2. R: 로봇이 향하고 있는 방향을 기준으로 오른쪽으로 90도 회전한다.
  3. F: 로봇이 향하고 있는 방향을 기준으로 앞으로 한 칸 움직인다.

간혹 로봇들에게 내리는 명령이 잘못될 수도 있기 때문에, 당신은 로봇들에게 명령을 내리기 전에 한 번 시뮬레이션을 해 보면서 안전성을 검증하려 한다. 이를 도와주는 프로그램을 작성하시오.

잘못된 명령에는 다음의 두 가지가 있을 수 있다.

  1. Robot X crashes into the wall: X번 로봇이 벽에 충돌하는 경우이다. 즉, 주어진 땅의 밖으로 벗어나는 경우가 된다.
  2. Robot X crashes into robot Y: X번 로봇이 움직이다가 Y번 로봇에 충돌하는 경우이다.

시물레이션 문제이다. 따로 알고리즘 능력을 요구하지는 않는 문제이므로 하라는 대로 구현만 하면 된다.

방향을 왼쪽 또는 오른쪽으로 회전시킬 때 방향만 회전시키고 해당 위치에서 움직이지는 않는다. 그러므로 모듈러연산을 통해 효율적으로 회전시킬 수 있도록 해준다.

 

그 외에는 정말 구현밖에 없어서 따로 적을 것이 없다. 코드로 확인하면 될 듯하다.

#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'

using namespace std;

int N, M, robotCnt, order, crashRobot;
int board[100 + 1][100 + 1];
vector<pair<pair<int, int>, int>> robot;
bool isCrashWall = false, isCrashRobot = false;

const int dy[] = {-1, 0, 1, 0};
const int dx[] = {0, 1, 0, -1};

int returnDir(char dir){
    if(dir == 'N') return 2;
    if(dir == 'E') return 1;
    if(dir == 'S') return 0;
    if(dir == 'W') return 3;
    return -1;
}

int changeDirRight(int dir){
    if(dir == 0) return 3;
    return dir-1;
}

int changeDirLeft(int dir){
    if(dir == 3) return 0;
    return dir+1;
}

void input(){
    cin >> N >> M;
    cin >> robotCnt >> order;
    for(int i=0;i<robotCnt;i++){
        int y, x; char dir;
        cin >> y >> x >> dir;
        robot.push_back({{x, y}, returnDir(dir)});
        board[x][y] = i+1;
    }
}

bool isValid(int y, int x){
    return (1 <= y && y <= M && 1 <= x && x <= N);
}

bool isCrashOtherRobot(int y, int x){
    return board[y][x] == 0 ? false : true;
}

void startMove(int robotNumber, char op, int cnt){
    if(op == 'L' || op == 'R') {
        cnt %= 4;

        int dir = robot[robotNumber-1].second;
        for(int i=0;i<cnt;i++){
            if(op=='L') dir = changeDirLeft(dir);
            if(op=='R') dir = changeDirRight(dir);
        }
        robot[robotNumber-1].second = dir;
    }
    else{
        for(int i=0;i<cnt;i++){
            int y = robot[robotNumber-1].first.first;
            int x = robot[robotNumber-1].first.second;
            int dir = robot[robotNumber-1].second;

            int ny = y + dy[dir];
            int nx = x + dx[dir];

            if(!isValid(ny, nx)) {
                isCrashWall = true;
                break;
            }
            if(isCrashOtherRobot(ny, nx)){
                isCrashRobot = true;
                crashRobot = board[ny][nx];
                break;
            }

            board[y][x] = 0;
            board[ny][nx] = robotNumber;
            robot[robotNumber-1].first.first = ny;
            robot[robotNumber-1].first.second = nx;
        }
    }
}

void solution(){
    char op;
    int robotNumber, repeatCnt;

    vector<pair<int, pair<char, int>>> ps;
    for(int i=0;i<order;i++){
        cin >> robotNumber >> op >> repeatCnt;
        ps.push_back({robotNumber, {op, repeatCnt}});
    }

    for(int i=0;i<ps.size();i++){
        isCrashRobot = false, isCrashWall = false;
        robotNumber = ps[i].first, op = ps[i].second.first, repeatCnt = ps[i].second.second;
       
        startMove(robotNumber, op, repeatCnt);
        if(isCrashWall == true){
            cout << "Robot " << robotNumber << " crashes into the wall" << endl;
            exit(0);
        }
        if(isCrashRobot == true){
            cout << "Robot " << robotNumber << " crashes into robot " << crashRobot << endl;
            exit(0);
        }
    }
    cout << "OK" << endl;
}

int main(void){
    fastio;
    input();
    solution();

    return 0;
}
728x90
반응형