Algorithm/BOJ
BAEK17825. 주사위 윷놀이
윤프라이즈
2023. 12. 8. 15:06
2023년 12월 8일
시간 : ❤❤❤🤍🤍
만족도 : ❤❤❤🤍🤍
- 각 경로를 나눈 것까지는 좋았으나, 25, 30, 35, 40에서 겹치는 경우를 처음에 생각하지 못했다.
- 또한 30에서 출발하는 경로에서 30이 중복되는 케이스 또한 생각하지 못해서 자꾸 틀렸다.
- 그래서 코드를 다 고치기 보다는 첫 스타트를 -30으로 바꿔준 뒤 -30을 총 점수에 더할 때는 절댓값 처리를 해준 후 더해주는 방식으로 해결하였다.
- 풀이 접근법은 좋았으나, 경우의 수를 자세하게 고려하지 못했던 것이 아쉽다.
코드
package algorithm_Java; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class BAEK17825 { static int[] turns = new int[10]; static int[] normal = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, -1}; static int[] specialTen = {10, 13, 16, 19, 25, 30, 35, 40, -1}; static int[] specialTwenty = {20, 22, 24, 25, 30, 35, 40, -1}; static int[] specialThirty = {-30, 28, 27, 26, 25, 30, 35, 40, -1}; // normal 0 // ten 1 // twenty 2 // thirty 3 // {0, 0} -> {현재있는 칸, 이동방식} static int[][] knights = {{0, 0}, {0, 0},{0, 0},{0, 0}}; static int result = Integer.MIN_VALUE; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); // 10개의 턴 for (int i = 0; i < 10; i++) turns[i] = Integer.parseInt(st.nextToken()); dfs(0, 0, knights); System.out.println(result); } public static void dfs(int turn, int score, int[][] knightStatus) { // base case if (turn == 10) { result = Math.max(result, score); return; } // recursive case for (int i = 0; i < 4; i++) { if (knightStatus[i][0] == -1) continue; int[] next = move(i, turns[turn], knightStatus); boolean check = true; for (int j = 0; j < 4; j++) { if (i != j) { if (next[1] == 0 && next[0] == 40) { if (next[0] == knightStatus[j][0]) { check = false; break; } } else if (next[1] == 1 || next[1] == 2 || next[1] == 3) { if (next[0] == 25 || next[0] == 30 || next[0] == 35 || next[0] == 40) { if (next[0] == knightStatus[j][0]) { check = false; break; } } } if (knightStatus[j][0] == next[0] && knightStatus[j][1] == next[1]) { if (next[0] == -1) continue; check = false; break; } } } if (!check) continue; int[][] temp = new int[4][2]; for (int j = 0; j < 4; j++) { if (i == j) { temp[j] = next; } else temp[j] = knightStatus[j]; } if (next[0] == -1) dfs(turn+1, score, temp); else dfs(turn+1, score + Math.abs(next[0]), temp); } } public static int[] move(int idx, int moving, int[][] knightStatus) { int[] knight = knightStatus[idx]; int[] next; // normal에 있을 때 if (knight[1] == 0) { int newIdx = 0; for (int i = 0; i < normal.length; i++) { if (normal[i] == knight[0]) { newIdx = i + moving; break; } } if (newIdx >= normal.length - 1) { next = new int[] {-1, 0}; } else if (normal[newIdx] == 20) { next = new int[] {20, 2}; } else if (normal[newIdx] == 30) { next = new int[] {-30, 3}; } else if (normal[newIdx] == 10) { next = new int[] {10, 1}; } else next = new int[] {normal[newIdx], 0}; // ten에 있을 때 } else if (knight[1] == 1) { int newIdx = 0; for (int i = 0; i < specialTen.length; i++) { if (specialTen[i] == knight[0]) { newIdx = i + moving; break; } } if (newIdx >= specialTen.length - 1) next = new int[] {-1, 1}; else next = new int[] {specialTen[newIdx], 1}; // Twenty에 있을 때 } else if (knight[1] == 2) { int newIdx = 0; for (int i = 0; i < specialTwenty.length; i++) { if (specialTwenty[i] == knight[0]) { newIdx = i + moving; break; } } if (newIdx >= specialTwenty.length - 1) next = new int[] {-1, 2}; else next = new int[] {specialTwenty[newIdx], 2}; // Thirty에 있을 때 } else { int newIdx = 0; for (int i = 0; i < specialThirty.length; i++) { if (specialThirty[i] == knight[0]) { newIdx = i + moving; break; } } if (newIdx >= specialThirty.length - 1) next = new int[] {-1, 3}; else next = new int[] {specialThirty[newIdx], 3}; } return next; } }