개발 무지렁이

[문제풀이] B17281 야구 본문

코딩 테스트/문제풀이

[문제풀이] B17281 야구

Gaejirang-e 2023. 6. 15. 16:29

야구


  🪅. 반복문을 돌릴때마다 조건에 맞는 '초기화'를 했는가? => 다음 반복에 영향을 주지 않게
  🪅. 일의 순서를 따질 때, '완전탐색 순열'을 생각해서 구현할 수 있는가? => '백트래킹'
  🪅. 순열의 '작업'과 문제 조건에 맞는 '로직'을 '분리'시켰는가 => 하나의 메서드는 '하나의 기능'만을 수행
  🪅. '전역변수'의 사용을 남용하지 않았는가? => '하나의 메서드 안'에서만 로직에 사용되는 데이터는 '지역변수'에 대입 
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.util.Arrays;
  import java.util.StringTokenizer;

  public class B17281_야구 {
      static int N;
      static int[][] input2d;
      static int[] selection;
      static boolean[] isSelected;
      static int maxScore;
      static int[] bases;

      public static int makeScore(int curResult) {
          int score = 0;
          switch(curResult) {
          case 1: //안타
              for(int i = 3; i >= 1; i--) {
                  if(bases[i] > 0) {
                      bases[i]--;
                      bases[i+1]++;
                  }
              }
              bases[1]++;
              while(bases[4] > 0) {
                  bases[4]--;
                  score++;
              }
              break;
          case 2: //2루타
              for(int i = 3; i >= 1; i--) {
                  if(bases[i] > 0) {
                      bases[i]--;
                      if(i+2 >= 4) {
                          bases[4]++;
                      } else {
                          bases[i+2]++;
                      }
                  }
              }
              bases[2]++;
              while(bases[4] > 0) {
                  bases[4]--;
                  score++;
              }
              break;
          case 3: //3루타
              for(int i = 3; i >= 1; i--) {
                  if(bases[i] > 0) {
                      bases[i]--;
                      score++;
                  }
              }
              bases[3]++;
              while(bases[4] > 0) {
                  bases[4]--;
                  score++;
              }
              break;
          case 4: //홈런
              for(int i = 3; i >= 1; i--) {
                  if(bases[i] > 0) {
                      score++;
                  }
              }
              score++;
              Arrays.fill(bases, 0);
              break;    
          }
          return score;
      }

      public static void gameStart() {
          int score = 0;
          int next = 0;
          int idx = 0;

          //모든 이닝이 끝날때까지
          for(int i = 0; i < N; i++) {
              int outCnt = 0;
              bases = new int[5];
              //3out이면 한 이닝 종료
              while(outCnt < 3) {
                  //9번선수까지 다돌면 다시 처음 선수
                  if(idx == 9) {
                      idx = 0;
                  }
                  int curResult = input2d[i][selection[idx]];
                  if(curResult == 0) {
                      outCnt++;
                  } else {
                      score += makeScore(curResult);
                  }
                  idx++;

              }
          }

          if(score > maxScore) {
              maxScore = score;
          }

          return;
      }
      public static void permutation(int r) {
          //종료조건
          if(r == 9) {
              gameStart();
              return;
          }

          //재귀적 확장
          //4번 타석은 이미 결정
          if(r == 3) {
              isSelected[0] = true;
              selection[r] = 0;
              permutation(r+1);
              return;
          }

          // 2번선수부터 9번선수까지
          for(int i = 1; i < 9; i++) {
              if(isSelected[i]) continue;
              isSelected[i] = true;
              selection[r] = i;

              permutation(r+1);
              isSelected[i] = false;//백트래킹
          }
      }
      public static void init() throws NumberFormatException, IOException {
          BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
          N = Integer.parseInt(br.readLine());
          input2d = new int[N][9];
          selection = new int[9];
          isSelected = new boolean[9];
          bases = new int[5];

          StringTokenizer token;

          for(int i = 0; i < N; i++) {
              token = new StringTokenizer(br.readLine(), " ");
              for(int j = 0; j < 9; j++) {
                  input2d[i][j] = Integer.parseInt(token.nextToken());
              }
          }
      }
      public static void main(String[] args) throws NumberFormatException, IOException {
          init();
          permutation(0);
          System.out.println(maxScore);
      }
  }  

💡. 문제 접근 과정
: 처음에는 순열(permutation)과 문제조건에 맞는 로직을 분리시키지 않아서 헷갈렸다.
그래서 permutation 안에서는 타자의 순서를 결정하는 작업만을 수행하고,
문제조건에 맞는 로직 gameStart()라는 메서드를 만들어서 분리시켰다.
또한, 전역변수와 메서드의 인자의 이름을 똑같이 해주는 바람에 거기서 로직이 꼬이기도 했다.
점수를 계산하는 과정에서도 무작정 로직을 작성하는 것이 아닌 case별로 나누고 나눠진 case에 따라,
로직을 작성
하는 것이 더 간단하며, 헷갈리지 않는 방법인 것 같다.

Tistory's Card

Comments