|
| 1 | +import java.io.BufferedReader; |
| 2 | +import java.io.IOException; |
| 3 | +import java.io.InputStreamReader; |
| 4 | +import java.util.StringTokenizer; |
| 5 | + |
| 6 | +public class boj_17281_야구공 { |
| 7 | + // 선수 선택 여부 체크용 (1~9번 타자 → true면 이미 순서에 포함됨) |
| 8 | + static boolean[] visited = new boolean[10]; |
| 9 | + // 타순을 저장 (1~9번 타순, order[4]은 고정 타자) |
| 10 | + static int[] order = new int[10]; |
| 11 | + static int ans = 0; // 최종 최대 점수 |
| 12 | + static int N; // 이닝 수 |
| 13 | + static int[][] graph; // graph[이닝][선수번호] = 결과 (0:아웃,1~4 안타) |
| 14 | + |
| 15 | + public static void main(String[] args) throws IOException { |
| 16 | + |
| 17 | + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); |
| 18 | + StringTokenizer st; |
| 19 | + N = Integer.parseInt(br.readLine()); |
| 20 | + graph = new int[N + 1][10]; |
| 21 | + |
| 22 | + // graph 입력받기 |
| 23 | + for (int i = 1; i <= N; i++) { |
| 24 | + st = new StringTokenizer(br.readLine()); |
| 25 | + for (int j = 1; j <= 9; j++) { |
| 26 | + graph[i][j] = Integer.parseInt(st.nextToken()); |
| 27 | + } |
| 28 | + } |
| 29 | + |
| 30 | + // 4번 타순(= index 4)에 1번 선수 고정 |
| 31 | + order[4] = 1; |
| 32 | + permu(1); // 1번 타순부터 조합 시작 |
| 33 | + System.out.println(ans); |
| 34 | + } |
| 35 | + |
| 36 | + // 현재 타순(order)에 대해 실제 경기 시뮬레이션 |
| 37 | + static int play() { |
| 38 | + int score = 0; |
| 39 | + int hitter = 1; // 현재 타석에 들어올 타순 번호 (1~9 반복) |
| 40 | + |
| 41 | + // 이닝 반복 |
| 42 | + for (int i = 1; i <= N; i++) { |
| 43 | + int base[] = new int[5]; // base[1]=1루, ..., base[4]=홈 |
| 44 | + int out = 0; |
| 45 | + |
| 46 | + // 3아웃 될 때까지 반복 |
| 47 | + while (out < 3) { |
| 48 | + int hit = graph[i][order[hitter]]; // 이번 타자가 친 결과 |
| 49 | + hitter = (hitter) % 9 + 1; // 다음 타자 순번 |
| 50 | + |
| 51 | + if (hit == 0) { // 아웃 |
| 52 | + out++; |
| 53 | + continue; |
| 54 | + } |
| 55 | + |
| 56 | + // 기존 주자들 이동 |
| 57 | + for (int j = 0; j < hit; j++) { |
| 58 | + base[4] += base[3]; |
| 59 | + base[3] = base[2]; |
| 60 | + base[2] = base[1]; |
| 61 | + base[1] = base[0]; |
| 62 | + } |
| 63 | + |
| 64 | + // 타자도 출루 |
| 65 | + base[hit]++; |
| 66 | + } |
| 67 | + |
| 68 | + // 홈으로 들어온 주자들 점수로 반영 |
| 69 | + score += base[4]; |
| 70 | + } |
| 71 | + return score; |
| 72 | + } |
| 73 | + |
| 74 | + // 4번 타순을 제외하고 나머지 타순을 완전탐색 (순열 생성) |
| 75 | + static void permu(int depth) { |
| 76 | + if (depth == 10) { // 1~9 모두 채움 |
| 77 | + ans = Math.max(ans, play()); |
| 78 | + return; |
| 79 | + } |
| 80 | + |
| 81 | + // 4번 타순은 이미 1번 선수로 고정돼 있으므로 건너뜀 |
| 82 | + if (depth == 4) { |
| 83 | + permu(depth + 1); |
| 84 | + return; |
| 85 | + } |
| 86 | + |
| 87 | + // 2~9번 선수들 중 아직 선택되지 않은 선수 선택 |
| 88 | + for (int i = 2; i <= 9; i++) { |
| 89 | + if (visited[i]) |
| 90 | + continue; |
| 91 | + visited[i] = true; |
| 92 | + order[depth] = i; |
| 93 | + permu(depth + 1); |
| 94 | + visited[i] = false; |
| 95 | + } |
| 96 | + } |
| 97 | +} |
0 commit comments