알고리즘

[백준, JAVA] 17281 공 ⚾️ (골드 4, 구현)

Lahezy 2023. 4. 6.
728x90

🔗 문제링크 🔗

https://www.acmicpc.net/problem/17281

 

17281번: ⚾

⚾는 9명으로 이루어진 두 팀이 공격과 수비를 번갈아 하는 게임이다. 하나의 이닝은 공격과 수비로 이루어져 있고, 총 N이닝 동안 게임을 진행해야 한다. 한 이닝에 3아웃이 발생하면 이닝이 종

www.acmicpc.net


🌟 생각 흐름 🌟

  1. 모든 가능한 선수들의 번호수를 깊이 우선탐색을 이용해서 구한다 ( 4번 타자는 1번으로 정해져 있다 )
  2. 선수들이 정해지면 점수를 매긴다. 
    1. 쓰리아웃이면 다음 이닝으로 넘어가고 그다음 플레이어(타자? 투수?)가 이어서 진행한다.
    2. 만약 0점이면 바로 아웃점수를 체크하고 넘어간다.
    3. 점수가 있는 경우
      1. 홈런인 경우는 1,2,3루수에 사람이 있는 경우 모두 점수로 체크한다.
      2. 1,2,3루수에 사람이 있으면 현재 있는 루수에 해당 이닝에서 발생한 점수를 더해서 4 이상이면 점수로 체크한다.
    4. 모든 점수의 최댓값을 구한다.

🍳 코드 🍳

package 백준.구현;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class boj_17281_공 {
    private static int inning;
    private static int[][] score;
    private static final int NINE = 9;
    private static final int[] permu = new int[NINE];
    private static final boolean[] visited = new boolean[NINE];
    private static int maxScore = 0;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        inning = Integer.parseInt(br.readLine());
        score = new int[inning][NINE];
        for (int j = 0; j < inning; j++) {
            st = new StringTokenizer(br.readLine());
            for (int i = 0; i < NINE; i++) {
                score[j][i] = Integer.parseInt(st.nextToken());
            }
        }

        // 4번째 타수는 이미 결정되었다.
        permu[3] = 0;
        visited[0] = true;
        dfs(0);
        System.out.println(maxScore);
    }

    private static void dfs(int nowDepth) {
        if (nowDepth == NINE) {
            // System.out.println(Arrays.toString(permu));
            checkScore();
        } else if (nowDepth == 3) {
            dfs(nowDepth + 1);
        } else {
            for (int i = 0; i < NINE; i++) {
                if (visited[i])
                    continue;

                visited[i] = true;
                permu[nowDepth] = i;
                dfs(nowDepth + 1);
                visited[i] = false;
            }
        }

    }

    private static void checkScore() {
        boolean[] people;

        int nowScore = 0;
        int outScore;
        int nowPlayer = 0;
        for (int i = 0; i < inning; i++) {
            people = new boolean[4];
            outScore = 0;
            while (outScore < 3) { // 3아웃
                nowPlayer %= 9;
                if (score[i][permu[nowPlayer]] == 0)
                    outScore++;
                else {
                    // 뒤에서 부터 가장 점수를 옮긴다.
                    int tempScore = score[i][permu[nowPlayer]];

                    if (tempScore == 4) {// 홈런
                        for (int k = 0; k <= 3; k++) {
                            if (people[k]) {
                                people[k] = false;
                                nowScore++;
                            }
                        }
                        nowScore++;// 자기자신까지
                    } else { // 1,2,3
                        for (int k = 3; 1 <= k; k--) {

                            if (people[k]) {
                                people[k] = false;
                                if (k + tempScore >= 4)
                                    nowScore++;
                                else
                                    people[k + tempScore] = true;
                            }
                        }
                        people[tempScore] = true;
                    }
                }
                nowPlayer++;
            }
        }
        // System.out.println(nowScore);
        maxScore = Math.max(nowScore, maxScore);
    }
}
728x90

댓글