짱아의 개발 기록장

백준 16985번. Maaaaaaaaaze(c++) / 구현 본문

Algorithm/Baekjoon

백준 16985번. Maaaaaaaaaze(c++) / 구현

jungahshin 2020. 8. 25. 13:49
반응형

골드3였지만...여러 가지 경우의 수를 고려해야 하는 구현 과정이 매우 복잡했던 문제...

물론, 구현하는 방법이 사람마다 가지 각색이지만 글쓴이는 매우 복잡하게 푼 것 같다ㅎ

 

1. 먼저, 층을 쌓았다 (5!) -> 아래 코드에서 stacked함수

2. 각 층을 회전시켜주었다.(4^5) -> 아래 코드에서 rotate함수

3. bfs로 최단 경로를 구해주었다. -> 아래 코드에서 bfs함수

 

 

코드 첨부

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
132
133
134
// Maaaaaaaaaze
#include <iostream>
#include <climits>
#include <cstring>
#include <queue>
using namespace std;
 
int maze[6][6][6= {0, };
int seq[6= {0, };
int final = INT_MAX;
int dh[6= {0000-11};
int dx[6= {00-1100};
int dy[6= {-110000};
 
int bfs(int nmaze [6][6][6])
{
    queue<pair<pair<intint>pair<intint>>> q;
    int Visited[6][6][6= {0, };
    q.push(make_pair(make_pair(00), make_pair(00)));
    while (!q.empty()) {
        int height = q.front().first.first;
        int x = q.front().first.second;
        int y = q.front().second.first;
        int cnt = q.front().second.second;
        Visited[height][x][y] = 1;
        q.pop();
 
        if(height==4 && x==4 && y==4){
            return cnt;
        }
 
        for(int k=0; k<6; k++){
            int nh = height+dh[k];
            int nx = x+dx[k];
            int ny = y+dy[k];
            if(0<=nh && nh<5 && 0<=nx && nx<5 && 0<=ny && ny<6 && !Visited[nh][nx][ny] && nmaze[nh][nx][ny]==1){
                Visited[nh][nx][ny] = 1;
                q.push(make_pair(make_pair(nh, nx), make_pair(ny, cnt+1)));
            }
        }
    }
 
    return -1;
}
 
void rotate(int height, int nmaze [6][6][6], int maze [6][6][6])
{
    if(height==5){
        if(nmaze[0][0][0]==1 && nmaze[4][4][4]==1){
            int temp = bfs(nmaze);
            if(temp != -1){
                final = min(final, temp);
            }
        }
        return;
    }
 
    // 반시계방향으로 회전하는 수
    for(int num=1; num<=4; num++){
        for(int i=0; i<5; i++){
            for(int j=0; j<5; j++){
                if(maze[height][i][j]==1){
                    if(num==1){
                        nmaze[height][j][4 - i] = 1;
                    }else if(num==2){
                        nmaze[height][4 - i][4 - j] = 1;
                    }else if(num==3){
                        nmaze[height][4 - j][i] = 1;
                    }else{
                        nmaze[height][i][j] = 1;
                    }
                }
            }
        }
 
        rotate(height+1, nmaze, maze);
        for(int i=0; i<5; i++){
            for(int j=0; j<5; j++){
                nmaze[height][i][j] = 0;
            }
        }
    }
}
 
void stacked(int cnt, int visited[6])
{
    if(cnt==5){
        int nmaze[6][6][6= {0, };
        for(int h=0; h<5; h++){
            int idx = seq[h];
            for(int i=0; i<5; i++){
                for(int j=0; j<5; j++){
                    nmaze[h][i][j] = maze[idx][i][j];
                }
            }
        }
 
        int temp [6][6][6= {0, };
        rotate(0, temp, nmaze);
        return;
    }
 
    for(int i=0; i<5; i++){
        if(visited[i]==truecontinue;
        visited[i] = true;
        seq[i] = cnt;
        stacked(cnt+1, visited);
        visited[i] = false;
        seq[i] = 0;
    }
    return;
}
 
int main()
{
    for(int h=0; h<5; h++){
        for(int i=0; i<5; i++){
            for(int j=0; j<5; j++){
                cin>>maze[h][i][j];
            }
        }
    }
 
    // 판을 쌓는다.
    int visited[6= {0, };
    stacked(0, visited);
    if(final==INT_MAX){
        cout<<"-1"<<"\n";
    }else{
        cout<<final<<"\n";
    }
 
    return 0;
}
cs

 

 

문제 첨부

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

 

16985번: Maaaaaaaaaze

첫째 줄부터 25줄에 걸쳐 판이 주어진다. 각 판은 5줄에 걸쳐 주어지며 각 줄에는 5개의 숫자가 빈칸을 사이에 두고 주어진다. 0은 참가자가 들어갈 수 없는 칸, 1은 참가자가 들어갈 수 있는 칸을

www.acmicpc.net

반응형
Comments