Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

희디비

[백준/G4/시뮬레이션/자바] 17281. ⚾ 본문

백준

[백준/G4/시뮬레이션/자바] 17281. ⚾

희디비 2024. 7. 14. 13:31

💡 문제

 

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

 

 

 입력

 

첫째줄 : N ( 2 <= N <= 50) 

둘째줄 : N의 수만큼 이닝의 결과 9개 반복

 

💻 출력 / 제한

 

이안타팀이 얻을 수있는 최대 점수 출력

 


 

풀이 방법

 

시뮬레이션 문제 입니다.

 

문제 풀이 순서는 다음과 같습니다.

 

1. 선수의 순열을 통해 순서를 찾는다  ( 단. 1번 타자의 순서는 4번째 )

2. 야구 게임을 한다.

→ 순열의 결과로 이닝의 타자 결과 배열을 만든다.
→ out ≠ 3 일때 까지 야구 게임을 한다.
→ 만약 타자의 결과가 안타 이상 이면 goRoo 함수를 통해 점수를 올린다.
→ 순열 별로 점수의 최대값을 갱신 한다.

 

순서 찾기 위한 순열

visited → 해당 번호의 선수가 뽑혔는가?

order[index] → index : 순서 / 값 → 선수의 번호

 

 

순서 다 정한 경우

 

안타 이상 친 경우

 

루에 있는 사람을 다 처리 했다면, 자신의 루로 가면 됩니다.

만약 홈런일 경우 점수 +1 / 아닐 경우 해당 루에 true 처리 하면 됩니다.

순열로 야구가 끝나면 점수의 최대값을 갱신 해주면 됩니다.

 


 

전체 코드

 

import java.io.*;
import java.util.StringTokenizer;

public class Baseball17281 {
    static int[][] arr;
    static int N;
    static int maxPoint = 0;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());

        arr = new int[N + 1][10];

        // 입력 받기
        StringTokenizer st;
        for(int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());

            for (int j = 1; j <= 9; j++) {
                arr[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        // 1 ~ 9 번 선수
        boolean[] visited = new boolean[10];
        // order index = 차례 order[i] = 몇번 타자
        int[] order = new int[10];

        // 4번 타자는 1번째
        order[4] = 1; visited[4] = true;
        permutation(2,order,visited);

        System.out.println(maxPoint);
    }

    // 순열 찾기
    static void permutation(int count, int[] order, boolean[] visited){
        // 9명의 선수를 찾은 재귀는 10을 호출
        if(count == 10){
            baseballPlay(order);
            return;
        }

        // visited[i] = i번째 선수 뽑았 는지, count = 몇 번째, order[i] = count -> i번째 선수는 count 타자 입니다.
        for(int i = 1; i <= 9; i++){
            if(!visited[i]) {
                visited[i] = true;
                order[i] = count;
                permutation(count + 1, order, visited);
                visited[i] = false;
            }
        }
    }

    static void baseballPlay(int[] order){
        int Point = 0;
        int batter = 0;

        for(int i = 1; i <= N; i++) {
            int out = 0;
            boolean[] roo = new boolean[4];
            int[] batterResult = makeArr(order,i);

            // 3아웃이 아니면
            while (out != 3) {
                int result = batterResult[batter % 9]; batter++;
                if(result == 0) out++;
                else Point += goRoo(roo,result);
            }
        }
        maxPoint = Math.max(Point,maxPoint);
    }

    // 타자의 결과에 따라 점수로 바꿔 줍니다.
    static int goRoo(boolean[] roo, int result){
        int Point = 0;

        for(int i = 3; i > 0; i--){
            if(roo[i]){
                if(i + result >= 4) {
                    Point++;
                    roo[i] = false;
                }
                else{
                    roo[i] = false;
                    roo[result + i] = true;
                }
            }
        }
        if(result != 4) roo[result] = true;
        else Point++;

        return Point;
    }

    // order[i] : 순번, arr[inning][order[i]] = 이닝의 타자의 결과
    static int[] makeArr(int[] order, int inning){
        int[] result = new int[9];

        for(int i = 1; i <= 9; i++){
            result[i-1] = arr[inning][order[i]];
        }
        return result;
    }
}