본문 바로가기
백준

[백준] code.plus(브루트 포스 Part 1,JAVA)17281번, ⚾

by 열정적인 이찬형 2022. 9. 2.

문제 링크

 

17281번: ⚾

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

www.acmicpc.net


주의사항

  • JAVA를 사용하여 프로그램을 사용하였습니다.
  • 백준에서 코드를 작성하였을 때 아래 형태에서 Main에서 결과가 출력되어야 합니다.
public class Main{ 	
	public static void main(String[] args){
    }
}

문제 설명


접근 방법

이 문제에 핵심은

 

1. 각 이닝에 대한 선수들의 타격 정보는 정해져있습니다.

2. 1번 선수는 항상 4번 타자입니다.

3. 1번을 제외한 선수들을 임의의 배치시 가장 득점을 많이하는 경우를 결과로 출력합니다.

4. 0 : 아웃, 1: 안타, 2 : 2루타, 3 : 3루타, 4 : 홈런

5. 야구는 N이닝동안 진행합니다.

 

알고리즘 진행 순서.

 

1. 입력되는 정보들을 저장합니다.

 

2. 1번을 제외한 선수들을 임의의 번호로 배치하는 모든 경우를 탐색합니다.

 

3. 모든 경우 탐색 후 득점을 가장 많이한 점수를 결과로 출력합니다.

 

타자

 

0 : 아웃

 

아웃 카운트가 1이 증가합니다.

 

1 : 안타

 

3루 → 득점

2루 → 3루

1루 → 2루

타자 → 1루

 

2 : 2루타

 

3루 → 득점

2루 → 득점

1루 → 3루

타자 → 2루

 

3 : 3루타

 

3루 → 득점

2루 → 득점

1루 → 득점

타자 → 3루

 

4 : 홈런

 

3루 → 득점

2루 → 득점

1루 → 득점

타자 → 득점

 

 

예제입력 2.

 

1. 입력되는 정보들을 저장합니다.

 

N = 2

4 0 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0

 

2. 1번을 제외한 선수들을 임의의 번호로 배치하는 모든 경우를 탐색합니다.

 

※선수를 배치하는 경우는 여러가지이지만 최대의 경우만 시뮬레이션 진행하는 것을 보여드리겠습니다.

 

선수 배치

5 6 7 1 2 3 4 8 9

 

야구 시작

 

1이닝.

1 1 1 4 0 0 0 0 0

 

1번 안타!

2번 안타!

3번 안타!

4번 홈런!

5, 6, 7번 아웃!

이닝 종료!

득점 : 4

 

2이닝.

8, 9, 1번 아웃!

이닝 종료!

득점 : 0

 

게임 종료

 

3. 모든 경우 탐색 후 득점을 가장 많이한 점수를 결과로 출력합니다.

 

최대 득점 4을 결과로 출력합니다.

 

  • BufferedReader를 사용하여 입력 값을 받았습니다.
  • StringTokenizer를 이용하여 입력값을 띄어쓰기 기준으로 나누었습니다.
  • search함수를 선수들 배치의 모든 경우를 구해서 야구게임을 진행합니다.
  • 모든 야구게임을 진행한 뒤 최대 득점을 BufferedWriter 저장하였습니다.
  • BufferedWriter에 저장된 결과값을 출력하였습니다.
  • search함수는 재귀를 통해서 선수를 타석에 배치하는 모든 경우를 탐색합니다.
  • play함수는 배치된 타석으로 야구 게임을 진행합니다.
  • playerMove함수는 선수들의 타격에 따라 선수들의 움직임을 진행합니다. 

 

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

public class Main {
    static int N, answer = 0;
    static int[][] player;	//각 이닝 선수들 타격 정보 저장 배열
    static boolean[] position;	//1,2,3루에 선수들 정보 저장 배열
    static boolean[] visited = new boolean[10];	//타선 배치시 선수 확인 배열
    static int[] select = new int[10];		//타선 정보
    public static void main(String[] args) throws IOException {
        //입력값 처리하는 BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //결과값 출력하는 BufferedWriter
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        N = Integer.parseInt(br.readLine());
        player = 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++)
                player[i][j] = Integer.parseInt(st.nextToken());
        }
        select[4] = 1;	//1번 선수 4번타자 임명!
        search(1);	//모든 타순 탐색
        bw.write(answer + "");	//최대 득점 BufferedWriter 저장
        bw.flush();		//결과 출력
        bw.close();
        br.close();
    }
    //1번 선수 제외한 모든 타선의 경우 탐색하는 함수
    static void search(int depth){
        if(depth==10){
            play();		//야구 게임 진행!
            return;
        }
        if(depth==4){		//4번 타자는 선택되었기 때문에 넘어갑니다.
            search(depth+1);
            return;
        }
        //선수들 탐색
        for(int i=2;i<=9;i++){
            if(visited[i])
                continue;
            visited[i] = true;
            select[depth] = i;
            search(depth+1);
            visited[i] = false;
        }
    }
    //야구게임 진행하는 함수
    static void play(){
        int inning = 1;		//이닝
        int curPlayer = 1;		//현재 타석의 선수 번호
        int score = 0;		//점수
        while(inning<=N){
            int outCount = 0;	//아웃 카운트
            position = new boolean[3];
            while(outCount<3){
                if(player[inning][select[curPlayer]]==0)	//0:아웃일 때
                    outCount++;
                else	//아웃을 제외한 타격일 때
                    score += playerMove(player[inning][select[curPlayer]]);

                //다음 선수로 변경
                if(curPlayer==9)
                    curPlayer=1;
                else
                    curPlayer++;
            }
            inning++;		//다음 이닝으로 변경
        }
        answer = Math.max(score, answer);
    }
    //타격에 따른 선수들 이동
    static int playerMove(int check){
        int score = 0;
        if(check==1){	//1 : 안타
            if(position[2])
                score++;
            position[2] = position[1];
            position[1] = position[0];
            position[0] = true;
        }else if(check==2){	//2 : 2루타
            for(int i=2;i>0;i--)
                if(position[i]){
                    score++;
                    position[i] = false;
                }
            position[2] = position[0];
            position[1] = true;
            position[0] = false;
        }else if(check==3){	//3 : 3루타
            for(int i=2;i>=0;i--)
                if(position[i]){
                    score++;
                    position[i] = false;
                }
            position[2] = true;
        }else{	//4 : 홈런
            for(int i=0;i<3;i++){
                if(position[i]){
                    score++;
                    position[i] = false;
                }
            }
            score++;
        }
        return score;
    }
}

댓글