-
백준 14499번: 주사위 굴리기 (Python/Java)Algorithm/Algorithm Problem 2022. 1. 13. 22:21
https://www.acmicpc.net/problem/14499
14499번: 주사위 굴리기
첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지
www.acmicpc.net
접근
굳이 다른 알고리즘을 쓰지 않더라도 풀 수 있는 구현 문제로, 조건에 맞춰 코드만 잘 작성하면 된다. 나 같은 경우는 주사위를 굴리고 또 아래, 위를 찾는 것이 조금 귀찮고, 머릿속에서 바로 그려지지 않았다. 때문에 그냥 따로 코드를 짜서 움직이는 방향과 주사위 상태만 넣으면 굴러간 주사위를 만들어주게끔 만들었다. 덕분에 위는 무조건 배열의 0번 인덱스, 바닥은 무조건 배열의 5번 인덱스로 찾으면 되었고, 간단하게 주사위 상태를 확인할 수 있었다.
예를 들어 문제에서 나온 주사위 구조를 숫자 순서대로 배열로 만들면 [1, 2, 3, 4, 5, 6]이 된다. 이제 아래는 0번 인덱스, 동쪽은 2번 인덱스로 고정하고 움직인다고 생각해보자. 동쪽으로 한 칸 움직이면 [4, 2, 1, 6, 5, 3], 서쪽은 [3, 2, 6, 1, 5, 4], 남쪽은 [2, 6, 3, 4, 1, 5], 마지막 북쪽으로 한 칸 움직이면 [5, 1, 3, 4, 6, 2]가 된다. 어느 쪽으로 움직이든 아래는 0번 인덱스, 동쪽은 2번 인덱스, 아래는 5번 인덱스가 된다. 이렇게 하면 문제를 풀 때 좀 더 편하게 풀 수 있다.
문제 조건에 범위 밖을 나가면 해당 명령은 무시하고 아무것도 출력하지 말라고 되어있는데, 범위를 구하는 코드 또한 따로 작성했다. 현재 위치와 방향을 넣어주면 범위 밖으로 나가면 [-1, -1]을 리턴하고, 범위 안이면 움직인 위치를 배열로 리턴하게 했다. 이렇게 구한 주사위와 움직인 위치를 토대로 결괏값을 찾으면 비교적 간단하게 정답을 맞힐 수 있다.
풀이
Python
def diceOrder(dice, direction): subDice = [] if direction == 1: subDice = [dice[3], dice[1], dice[0], dice[5], dice[4], dice[2]] elif direction == 2: subDice = [dice[2], dice[1], dice[5], dice[0], dice[4], dice[3]] elif direction == 3: subDice = [dice[4], dice[0], dice[2], dice[3], dice[5], dice[1]] elif direction == 4: subDice = [dice[1], dice[5], dice[2], dice[3], dice[0], dice[4]] return subDice def locationOrder(thisHeight, thisWidth, direction): if direction == 1: thisWidth += 1 elif direction == 2: thisWidth -= 1 elif direction == 3: thisHeight -= 1 elif direction == 4: thisHeight += 1 if 0 <= thisHeight < height and 0 <= thisWidth < width: return [thisHeight, thisWidth] else: return [-1, -1] height, width, thisHeight, thisWidth, roundNum = map(int, (input()).split()) board = [list(map(int, (input()).split())) for i in range(height)] orderList = list(map(int, (input()).split())) result = "" dice = [0, 0, 0, 0, 0, 0] for i in range(roundNum): thisLocation = locationOrder(thisHeight, thisWidth, orderList[i]) if thisLocation[0] != -1 and thisLocation[1] != -1: dice = diceOrder(dice, orderList[i]) thisHeight = thisLocation[0] thisWidth = thisLocation[1] if board[thisHeight][thisWidth] == 0: board[thisHeight][thisWidth] = dice[5] else: dice[5] = board[thisHeight][thisWidth] board[thisHeight][thisWidth] = 0 result += str(dice[0]) + "\n" print(result)
Java
import java.util.Scanner; public class Java { static int height, width; public static void main(String[] args) { Scanner scan = new Scanner(System.in); String[] firstLine = (scan.nextLine()).split(" "); height = Integer.parseInt(firstLine[0]); width = Integer.parseInt(firstLine[1]); int thisHeight = Integer.parseInt(firstLine[2]); int thisWidth = Integer.parseInt(firstLine[3]); int roundNum = Integer.parseInt(firstLine[4]); int[][] board = new int[height][width]; for(int i = 0 ; i < height ; i++){ String[] secondLine = (scan.nextLine()).split(" "); for(int j = 0 ; j < width ; j++){ board[i][j] = Integer.parseInt(secondLine[j]); } } int[] orderList = new int[roundNum]; String[] secondLine = (scan.nextLine()).split(" "); for(int i = 0 ; i < roundNum ; i++){ orderList[i] = Integer.parseInt(secondLine[i]); } String result = ""; int[] dice = {0, 0, 0, 0, 0, 0}; for(int i = 0 ; i < roundNum ; i++){ int[] thisLocation = locationOrder(thisHeight, thisWidth, orderList[i]); if(thisLocation[0] != -1 && thisLocation[1] != -1){ dice = diceOrder(dice, orderList[i]); thisHeight = thisLocation[0]; thisWidth = thisLocation[1]; if(board[thisHeight][thisWidth] == 0){ board[thisHeight][thisWidth] = dice[5]; }else{ dice[5] = board[thisHeight][thisWidth]; board[thisHeight][thisWidth] = 0; } result += (Integer.toString(dice[0]) + "\n"); } } System.out.println(result); } private static int[] diceOrder(int[] dice, int direction){ int[] subDice = new int[6]; if(direction == 1){ subDice = new int[] {dice[3], dice[1], dice[0], dice[5], dice[4], dice[2]}; }else if(direction == 2){ subDice = new int[] {dice[2], dice[1], dice[5], dice[0], dice[4], dice[3]}; }else if(direction == 3){ subDice = new int[] {dice[4], dice[0], dice[2], dice[3], dice[5], dice[1]}; }else if(direction == 4){ subDice = new int[] {dice[1], dice[5], dice[2], dice[3], dice[0], dice[4]}; } return subDice; } private static int[] locationOrder(int thisHeight, int thisWidth, int direction){ if(direction == 1){ thisWidth++; }else if(direction == 2){ thisWidth--; }else if(direction == 3){ thisHeight--; }else if(direction == 4){ thisHeight++; } int[] subLocation = new int[2]; if(thisHeight >= 0 && thisHeight < height && thisWidth >= 0 && thisWidth < width){ subLocation = new int[] {thisHeight, thisWidth}; }else{ subLocation = new int[] {-1, -1}; } return subLocation; } }
후기
굳이 어떤 알고리즘을 찾을 필요가 없는 완전 쌩 구현 문제였다. 구현 문제를 풀 때마다 항상 하는 생각은 '정신만 차리면 산다'는 것이다. 조건만 잘 맞춰 코드를 작성하면 누구나 다 맞출 수 있다고 생각한다. 물론 현재 푸는 난이도가 그렇게 어려운 난이도가 아니라 그런 거라고 생각할 수 있지만, 난이도가 높아져도 그럴 것이라 생각한다.
반대로 조금만 방심하면 바로 틀리는 것이 구현 문제다. 실제로 이번 문제를 풀 때에도 구현 방식은 다 잘 생각해놓고 정작 작성할 때에는 한 줄을 3번을 남쪽으로, 4번을 북쪽으로 계산하도록 작성해서 틀렸다. 이렇게 인덱스 번호 몇 개 틀린 것은 눈에 잘 띄지도 않는다. 정신 똑바로 차리고 쉬운 구현 문제에서 방심하는 일 없도록 조심하자.
'Algorithm > Algorithm Problem' 카테고리의 다른 글
백준 3055번: 탈출 (Python/Java) (0) 2022.01.15 백준 16206번: 롤케이크 (Python/Java) (0) 2022.01.14 백준 5427번: 불 (Python/Java) (0) 2022.01.12 백준 18513번: 샘터 (Python/Java) (0) 2022.01.11 백준 1092번: 배 (Python/Java) (0) 2022.01.10