본문 바로가기
백준

[백준 1938] 통나무 옮기기, C++

by 황인태(intaehwang) 2020. 3. 30.
반응형

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

 

1938번: 통나무 옮기기

첫째 줄에 주어진 평지의 한 변의 길이 N이 주어진다. (4<=N<=50) 주어진다. 이어서 그 지형의 정보가 0, 1, B, E로 이루어진 문자열로 주어진다. 한 줄에 입력되는 문자열의 길이는 N이며 입력 문자 사이에는 빈칸이 없다. 통나무와 최종 위치의 개수는 1개이다.

www.acmicpc.net

https://programmers.co.kr/learn/courses/30/lessons/60063

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

본 문제는 프로그래머스 - level 3, 블록 이동하기를 풀다가 못풀어서 비슷한 문제를 찾다가 푼 문제다. BFS문제는 잘 푼다고 생각했는데 구현 난이도가 증가하면 못풀고 있다. 구현 문제를 좀 더 열심히 풀어야겠다. 통나무는 상하좌우 움직일 수 있으며 통나무를 둘러싸고 있는 3x3 구역에 나무가 없을 때 90도 회전할 수 있다.

  1. 배열을 입력 받을 때, 통나무(B)와 출구(E)를 0으로 바꾼다.
  2. 통나무가 가로 또는 세로로 어떻게 배치되었는지 확인한다.
  3. 출구도 어떻게 배치되었는지 확인한다.
  4. chk[][][] 배열로 가로일 때, 세로일 때 1번 씩 방문하도록 확인한다.
  5. queue를 돌리면서 가운데 통나무를 기준으로 출구에 도착하였는지 확인한다.
  6. 상하좌우로 이동한다.
  7. 가운데 통나무를 기준으로 3x3의 크기에 나무가 있는지 확인한다.
  8. 없으면 회전한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <tuple>
 
using namespace std;
 
char map[51][51];
bool chk[51][51][2];
// 0 : 가로
// 1 : 세로
 
int dx[] = {1-100};
int dy[] = {001-1};
int n;
 
bool is_right(int nx, int ny, int z) {
    if (chk[nx][ny][z]) return false;
    if (z == 0) {
        if (nx >= 0 && nx < n && ny-1 >= 0 && ny+1 < n) {
            if (map[nx][ny-1== '0' && map[nx][ny] == '0' && map[nx][ny+1== '0') {
                return true;
            }
        }
    }
    else if (z == 1) {
        if (nx-1 >= 0 && nx+1 < n && ny >= 0 && ny < n) {
            if (map[nx-1][ny] == '0' && map[nx][ny] == '0' && map[nx+1][ny] == '0') {
                return true;
            }
        }
    }
    return false;
}
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    cin >> n;
 
    vector<pair<intint>> B;
    vector<pair<intint>> E;
    for (int i = 0; i < n; i++) {
        string s;
        cin >> s;
        for (int j = 0; j < s.size(); j++) {
            map[i][j] = s[j];
            if (s[j] == 'B') {
                map[i][j] = '0';
                B.push_back(make_pair(i, j));
            }
            if (s[j] == 'E') {
                map[i][j] = '0';
                E.push_back(make_pair(i, j));
            }
        }
    }
 
    int shapeB, shapeE;
    if (B[0].first == B[1].first && B[0].first == B[2].first) {
        shapeB = 0;
    }
    if (B[0].second == B[1].second && B[0].second == B[2].second) {
        shapeB = 1;
    }
 
    if (E[0].first == E[1].first && E[0].first == E[2].first) {
        shapeE = 0;
    }
    if (E[0].second == E[1].second && E[0].second == E[2].second) {
        shapeE = 1;
    }
 
    queue<tuple<intintintint>> q;
    q.push(make_tuple(B[1].first, B[1].second, shapeB, 0));
    chk[B[1].first][B[1].second][shapeB] = true;
 
    int ans = -1;
    while (!q.empty()) {
        int x, y, z, w;
        tie(x, y, z, w) = q.front();
        q.pop();
        if (E[1].first == x && E[1].second == y && shapeE == z) {
            ans = w;
        }
        for (int k = 0; k < 4; k++) {
            int nx = x + dx[k];
            int ny = y + dy[k];
            if (z == 0) {
                if (is_right(nx, ny, z)) {
                    chk[nx][ny][z] = true;
                    q.push(make_tuple(nx, ny, z, w+1));
                }
            }
            else if (z == 1) {
                if (is_right(nx, ny, z)) {
                    chk[nx][ny][z] = true;
                    q.push(make_tuple(nx, ny, z, w+1));
                }
            }
        }
        bool flag = false;
        if (x-1 >= 0 && x+1 < n && y-1 >= 0 && y+1 < n) {
            for (int i = x-1; i < x+2; i++) {
                for (int j = y-1; j < y+2; j++) {
                    if (map[i][j] == '1') flag = true;
                }
            }
        }
 
        if (flag) continue;
        
        if (z == 0) {
            if (is_right(x, y, 1)) {
                chk[x][y][1= true;
                q.push(make_tuple(x, y, 1, w+1));
            }
        }
        else if (z == 1) {
            if (is_right(x, y, 0)) {
                chk[x][y][0= true;
                q.push(make_tuple(x, y, 0, w+1));
            }
        }
    }
    if (ans == -1cout << "0\n";
    else cout << ans << "\n";
}
cs
반응형

'백준' 카테고리의 다른 글

[백준 15683] 감시, C++  (0) 2020.04.16
[백준 15662] 톱니바퀴 (2), C++  (0) 2020.04.12
[백준 1005] ACM Craft, C++  (0) 2020.03.22
[백준 16926] 배열 돌리기 1, C++  (0) 2020.03.12
[백준 16234] 인구 이동, C++  (0) 2020.03.10
Buy me a coffeeBuy me a coffee

댓글