Problem
문제에서 시키는 대로 주사위를 굴리는 문제입니다.
Solution
특별한 알고리즘은 없고 문제에서 제시한 대로 구현만 해주면 됩니다.
언뜻 보면 굉장히 복잡한 것 같지만 주사위가 동, 서, 남, 북으로 이동하는 부분만 하드코딩 해주면 간단하게 풀립니다.
저는 Dice
라는 클래스를 만들어서 주사위 6면의 값을 저장했습니다.
방향은 동쪽은 1, 서쪽은 2, 북쪽은 3, 남쪽은 4
기 때문에 dx
, dy
배열을 만들때 저 순서대로 만든 후에 1씩 빼주면 됩니다.
함정에 빠질만한 부분이라면 지도의 값이 0이 아닐때 주사위 바닥에 복사를 하는데, 복사 하고 나면 지도값은 0이 되는겁니다.
순서는 문제에 나와있는 대로
- 입력받은 방향만큼
for
문 - 움직인 이후의 값이 지도를 벗어나는지 확인
- 주사위 이동
- 숫자 복사
- 맨 윗면 출력
이 순서대로 k
번만큼 진행하면 됩니다.
주사위를 이동시킬 때 자바는 temp
값을 사용했지만 파이썬은
x, y = y, x
이렇게 두개의 값을 바꿀수 있다는 특성을 이용하여 구현할 수 있습니다.
Java Code
import java.util.*;
import java.io.*;
class Main {
static class Dice {
int top, bottom, west, east, south, north;
public Dice() {
this.top = 0;
this.bottom = 0;
this.west = 0;
this.east = 0;
this.south = 0;
this.north = 0;
}
public void moveEast() {
int temp = top;
top = west;
west = bottom;
bottom = east;
east = temp;
}
public void moveWest() {
int temp = top;
top = east;
east = bottom;
bottom = west;
west = temp;
}
public void moveSouth() {
int temp = top;
top = north;
north = bottom;
bottom = south;
south = temp;
}
public void moveNorth() {
int temp = top;
top = south;
south = bottom;
bottom = north;
north = temp;
}
public void printTopNumber() {
System.out.println(top);
}
}
static int n, m, x, y, k;
static int[][] map;
static int[] dir;
static int[] dx = {0, 0, -1, 1}; // 동서북남
static int[] dy = {1, -1, 0, 0};
static int stoi(String s) {
return Integer.parseInt(s);
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = stoi(st.nextToken());
m = stoi(st.nextToken());
x = stoi(st.nextToken());
y = stoi(st.nextToken());
k = stoi(st.nextToken());
map = new int[n][m];
dir = new int[k];
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
map[i][j] = stoi(st.nextToken());
}
}
st = new StringTokenizer(br.readLine());
for (int i = 0; i < k; i++) {
dir[i] = stoi(st.nextToken());
}
solution();
}
static void solution() {
Dice dice = new Dice();
int nx, ny;
for (int i = 0; i < k; i++) {
int direction = dir[i] - 1;
nx = x + dx[direction];
ny = y + dy[direction];
if (0 <= nx && nx < n && 0 <= ny && ny < m) {
// 동쪽은 0, 서쪽은 1, 북쪽은 2, 남쪽은 3
if (direction == 0) dice.moveEast();
else if (direction == 1) dice.moveWest();
else if (direction == 2) dice.moveNorth();
else if (direction == 3) dice.moveSouth();
// 숫자 복사
if (map[nx][ny] == 0)
map[nx][ny] = dice.bottom;
else {
dice.bottom = map[nx][ny];
map[nx][ny] = 0;
}
// 맨 윗면 출력
dice.printTopNumber();
x = nx;
y = ny;
}
}
}
}
Python Code
# -*- coding: utf-8 -*-
import sys
N = M = K = 0
arr = []
## 동 서 북 남
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]
## x, y 좌표와 주사위 상단/하단/동/서/남/북 면에 있는 숫자
class Dice:
def __init__(self, x, y, top, bottom, e, w, n, s):
self.x = x
self.y = y
self.top = top
self.bottom = bottom
self.e = e
self.w = w
self.n = n
self.s = s
def move(dice, d):
nx = dice.x + dx[d]
ny = dice.y + dy[d]
## 지도 밖으로 안나가야 됨
if 0 <= nx and nx < N and 0 <= ny and ny < M:
dice.x = nx
dice.y = ny
## 동 서 북 남
if d == 0:
dice.top, dice.bottom, dice.w, dice.e = dice.w, dice.e, dice.bottom, dice.top
elif d == 1:
dice.top, dice.bottom, dice.w, dice.e = dice.e, dice.w, dice.top, dice.bottom
pass
elif d == 2:
dice.top, dice.bottom, dice.n, dice.s = dice.s, dice.n, dice.top, dice.bottom
elif d == 3:
dice.top, dice.bottom, dice.n, dice.s = dice.n, dice.s, dice.bottom, dice.top
## 이동한 칸이 0이면 주사위 바닥면 복사
## 이동한 칸이 0이 아니면 주사위 바닥면에 숫자 복사하고 칸은 0
if arr[dice.x][dice.y] == 0:
arr[dice.x][dice.y] = dice.bottom
else:
dice.bottom = arr[dice.x][dice.y]
arr[dice.x][dice.y] = 0
else:
return False
return True
def solve(x, y, directions):
dice = Dice(x, y, 0, 0, 0, 0, 0, 0)
for direction in directions:
if move(dice, direction-1) == True:
print(dice.top)
if __name__ == '__main__':
N, M, x, y, K = map(int, sys.stdin.readline().split())
for i in range(N):
arr.append(list(map(int, sys.stdin.readline().split())))
directions = list(map(int, sys.stdin.readline().split()))
solve(x, y, directions)
'알고리즘 문제 > Samsung' 카테고리의 다른 글
백준 14502번. 연구소 (Java, Python) (5) | 2018.12.28 |
---|---|
백준 14500번. 테트로미노 (Java, Python) (2) | 2018.12.27 |
백준 14888번. 연산자 끼워넣기 (Java, Python) (0) | 2018.12.27 |
백준 13458번. 시험 감독 (Java, Python) (0) | 2018.12.21 |
백준 14501번. 퇴사 (Java, Python) (0) | 2018.12.19 |