본문 바로가기

알고리즘/백준

[백준] 2873번 롤러코스터

반응형

롤러코스터(https://www.acmicpc.net/problem/2873)


1. 이해하기

  • 가장 큰 기쁨을 주는 롤러코스터의 움직임을 출력하는 문제.

  • 행 혹은 열이 홀수인 경우, 모든 지역 탐색이 가능하다.

  • 행, 열이 모두 짝수인 경우에는 어느 한 지역을 가지 않아야 한다.

    • 가지 않는 한 지역을 구하는 기준은 다음과 같다.
      • (행+열)이 홀수인 지역 중 가장 행복 지수가 낮은 지역을 구한다.
      • 이유는 (행+열)이 짝수인 지역을 가지 않을 경우 한 곳은 두번 이상을 거쳐야 가장 오른쪽 아래 칸에 도착을 할 수 있기 때문이다.
  • 가지 않는 지역을 결정했으면 그 지역을 기준으로 출발지역과 끝지역에서 서로 만나는 코스를 만든다고 생각한다.

    1. 가지 않는 지역을 기준으로 출발지역에서는 아래로 2칸, 끝지역에서는 위로 2칸을 갈 수 있는지 본다. 그리고 출발지역과 끝지역의 행 차이가 1인 지역에서 멈춘다.

    2. 그 다음에는 가지 않는 지역을 기준으로 옆으로 옆으로 2칸을 갈 수 있는지 본다. 마찬가지로 출발지역과 끝지역의 열 차이가 1인 지역에서 멈춘다.

    3. 마지막에는 위쪽으로 갈 수 있는지, 아래쪽으로 갈 수 있는지를 체크해서 방향을 넣어준다.


2. 구현하기

#include <iostream>
#include <algorithm>
using namespace std;

int happy[1000][1000];

void append(string& ans, char c, int end) {
    for(int i = 0; i < end; i++) {
        ans += c;
    }
}

int main() {
    int R,C;
    cin >> R >> C;
    for(int i = 0; i < R; i++)
        for(int j = 0; j < C; j++)
            cin >> happy[i][j];

    if(R%2==1) {
        string ans = "";
        bool r = true;
        for(int i = 0; i < R; i++) {
            if(r) {
                append(ans,'R',C-1);
                r = !r;
            } else {
                append(ans,'L',C-1);
                r = !r;
            }
            if(i+1 < R) ans += 'D';
        }
        cout << ans << '\n';
    } else if(C%2 == 1) {
        string ans = "";
        bool d = true;
        for(int i = 0; i < C; i++) {
            if(d) {
                append(ans,'D',R-1);
                d = !d;
            } else {
                append(ans,'U',R-1);
                d = !d;
            }
            if(i+1 < C) ans += 'R';
        }
        cout << ans << '\n';
    } else {
        int x = 0,y = 1;
        int minVal = happy[0][1];
        for(int i = 0; i < R; i++) {
            for(int j = 0; j < C; j++) {
                if((i+j)%2 == 1 and minVal > happy[i][j]) {
                    minVal = happy[i][j];
                    x = i; y = j;
                }
            }
        }
        string ans = "", revAns = "";
        int sr = 0, sc = 0, er = R-1, ec = C-1;
        while(er - sr > 1) {
            if(sr+1 < x) {
                append(ans,'R',C-1);
                append(ans,'D',1);
                append(ans,'L',C-1);
                append(ans,'D',1);
                sr+=2;
            }
            if(er-1 > x) {
                append(revAns,'R',C-1);
                append(revAns,'D',1);
                append(revAns,'L',C-1);
                append(revAns,'D',1);
                er -= 2;
            }
        }
        while(ec - sc > 1) {
            if(sc+1 < y) {
                append(ans,'D',1);
                append(ans,'R',1);
                append(ans,'U',1);
                append(ans,'R',1);
                sc += 2;
            }
            if(ec-1 > y) {
                append(revAns,'D',1);
                append(revAns,'R',1);
                append(revAns,'U',1);
                append(revAns,'R',1);
                ec -= 2;
            }
        }
        if(x == sr+1) {
            append(ans,'R',1);
            append(ans,'D',1);
        } else if(x == er-1) {
            append(ans,'D',1);
            append(ans,'R',1);
        }
        reverse(revAns.begin(),revAns.end());
        ans += revAns;
        cout << ans << '\n';
    }
    return 0;
}

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 2263번 트리의 순회  (1) 2019.12.16
[백준] 10815번 숫자 카드  (0) 2019.12.11
[백준] 2098번 외판원 순회  (0) 2019.11.13
[백준] 1967번 트리의 지름  (0) 2019.11.06
[백준] 17822번 원판 돌리기  (0) 2019.10.24