반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 연방준비제도(FRS)/연방준비은행(FRB)
- 원금리스크
- 경제 기사읽기
- 특수목적기구
- 자의식 해체
- 부동산 기사읽기
- 엥겔의법칙
- 경제금융용어
- 경제기사 읽기
- 업무지구별
- 제로금리정책
- KFO
- 유전자오작동
- 황농문 서울대교수
- 부동산기사읽기
- 역행자
- 백준 파티
- 급여액
- 자발적 실업
- 행크TV
- 구해줘월부
- 월부TV
- 평균급여액
- 백준 1238
- 매일경제
- 웅덩이 매매법
- 한국직업개발원
- 이중통화채(dual currency bond)
- 경제적 자유를 위한 5가지 공부법
- 정체성 만들기
Archives
- Today
- Total
록키의 No Pain, No Gain
[BOJ] 16895번 Maaaaaaaaaze 본문
반응형
https://www.acmicpc.net/problem/16985
16985번: Maaaaaaaaaze
첫째 줄부터 25줄에 걸쳐 판이 주어진다. 각 판은 5줄에 걸쳐 주어지며 각 줄에는 5개의 숫자가 빈칸을 사이에 두고 주어진다. 0은 참가자가 들어갈 수 없는 칸, 1은 참가자가 들어갈 수 있는 칸을 의미한다.
www.acmicpc.net
문제
5 * 5 * 5 3차원 큐브를 각 층을 시계, 반시계 방향으로 회전시키고, 쌓아서 끝에서 끝으로 이동하는 최단거리를 구하는 문제이다.
풀이
이 문제는 문항이 길고 시뮬레이션 + BackTraking + BFS를 조합한 문제로 삼성 SW 역량테스트를 준비하기 아주 좋은 문제인듯...
- 먼저 각 층을 회전한다. 각 층이 회전하는 경우가 4가지 이므로 4 ^ 5가지의 경우의 수가 나오겠으나..... 원순열을 구하는 원리를 생각해볼때 중복된 경우가 많이나온다. 따라서 맨 윗층을 고정시켜 주었다.
- 모든 층을 회전시켜 줄 때마다, 쌓아준다. 쌓는 경우는 next_permutation을 이용하거나 BackTraking을 이용하여 순열을 구하여 쌓아주면 되겠다.
- 이후에 입구가 (0,0,0),(0,0,4),(0,4,0),(0,4,4)인 경우로 나누어 BFS로 (4,4,4),(4,4,0),(4,0,4),(4,0,0)까지 가는 최단 거리를 구해주면 된다. 이때 이미 answer가 12인 경우에는 더 이상 최단 거리가 나올 수 없으므로 break를 걸어준다.
실수 했던 부분
- 우선, 출발점이나 도착점이 0인 경우를 배제해 주지 않았다. 문제를 제대로 읽지 않아서 생긴 문제이다. 왜 계속 이런 실수를 할까..... 문제를 정확히 2번 읽고 모든 경우를 다 생각해야한다. 문제 오래 읽어서 손해볼 거 없으니 조급해하지 말것
- 그리고 정답을 내는덴 상관 없었지만, answer가 12일 경우 가지치기를 하지 않았다. 항상 최적화 염두하기.
#include <iostream>
#include <queue>
#include <utility>
#include <algorithm>
using namespace std;
int arr[5][5][5];
int cnt = 0;
int rotateResult[5][5][5];
int maze[5][5][5];
bool visited[5][5][5];
int a[5];
int answer = 5 * 5 * 5;
int dy[6] = { 0, 0, -1, 1, 0, 0 };
int dx[6] = { -1, 1, 0, 0, 0, 0 };
int dz[6] = { 0, 0, 0, 0, -1, 1 };
struct Point {
int y;
int x;
int z;
};
void bfs(int sy, int sx, int sz, int ey, int ex, int ez) {
if (maze[sy][sx][sz] == 0 || maze[ey][ex][ez] == 0) return;
queue<Point> q;
q.push({ sy,sx,sz });
visited[sy][sx][sz] = true;
int t = -1;
while (!q.empty()) {
t++;
int sze = q.size();
for (int j = 0; j < sze; j++) {
int currY = q.front().y;
int currX = q.front().x;
int currZ = q.front().z;
q.pop();
if (currY == ey && currX == ex && currZ == ez) {
answer = (answer < t) ? answer : t;
return;
}
for (int i = 0; i < 6; i++) {
int nextY = currY + dy[i];
int nextX = currX + dx[i];
int nextZ = currZ + dz[i];
if (nextY < 0 || nextX < 0 || nextZ < 0 || nextY > 4 || nextX > 4 || nextZ > 4) continue;
if (visited[nextY][nextX][nextZ]) continue;
if (maze[nextY][nextX][nextZ] == 0) continue;
q.push({ nextY, nextX, nextZ });
visited[nextY][nextX][nextZ] = true;
}
}
}
}
void pile() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
maze[a[i]][j][k] = rotateResult[i][j][k];
}
}
}
}
void init() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
visited[i][j][k] = false;
}
}
}
}
void rotate(int i, int d) {
if (d == 0) {
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
rotateResult[i][j][k] = arr[i][j][k];
}
}
}
else if (d == 1) {
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
rotateResult[i][j][k] = arr[i][4 - k][j];
}
}
}
else if (d == 2) {
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
rotateResult[i][j][k] = arr[i][4 - j][4 - k];
}
}
}
else if (d == 3) {
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
rotateResult[i][j][k] = arr[i][k][4 - j];
}
}
}
}
int main() {
//입력
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
cin >> arr[i][j][k];
}
}
}
//회전
bool flag = false;
rotate(0, 0);
for (int j = 0; j < 4; j++) {
rotate(1, j);
for (int k = 0; k < 4; k++) {
rotate(2, k);
for (int l = 0; l < 4; l++) {
rotate(3, l);
for (int m = 0; m < 4; m++) {
rotate(4, m);
//쌓는다.
for (int i = 0; i < 5; i++) a[i] = i;
do {
//쌓는다.
pile();
//입구, 출구 정한다.
bfs(0, 0, 0, 4, 4, 4);
if (answer == 12) {
flag = true;
break;
}
init();
bfs(0, 4, 0, 4, 0, 4);
if (answer == 12) {
flag = true;
break;
}
init();
bfs(4, 0, 0, 0, 4, 4);
if (answer == 12) {
flag = true;
break;
}
init();
bfs(4, 4, 0, 0, 0, 4);
if (answer == 12) {
flag = true;
break;
}
init();
} while (next_permutation(a, a + 5));
if(flag) break;
}
if(flag) break;
}
if(flag) break;
}
if(flag) break;
}
if (answer == 5 * 5 * 5) cout << -1;
else cout << answer;
}
반응형
'알고리즘' 카테고리의 다른 글
[BOJ] 17471번 게리멘더링 (0) | 2020.04.28 |
---|---|
[BOJ] 17822번 원판 돌리기 (0) | 2020.04.28 |
[BOJ] 17825 주사위 윷놀이 (0) | 2020.04.28 |
[BOJ] 17142번 연구소 3 (0) | 2020.04.26 |
[BOJ] 18809 Gaaaaaaaaaarden (0) | 2020.04.21 |
Comments