[백준] 1107번: 리모컨

ByWindow·2022년 1월 19일
0

Algorithm

목록 보기
71/104
post-thumbnail

📝 문제

문제 해결의 로직을 살펴보면,
목표 채널에 가장 빠르게 이동하기 위해서 번호키를 이용하여 이동할 수 있는 목표 채널과 가장 가까운 채널로 이동한 후, +-버튼을 이용하여 부족한 이동을 마무리한다.
따라서 브루트포스의 선형탐색 알고리즘으로 n에서 1을 더하거나 빼면서 해당 수가 숫자키로 만들 수 있는지 체크하고 그냥 100에서 +-버튼으로 이동할 때와 번호키 입력 후 +- 누를 때를 비교하여 더 적은 횟수를 출력하면 된다.

힘들었던 부분 & 보완할 부분

  • while(true)로 반복하므로 모든 예외상황에 대해서 생각해야된다. 어떤 케이스에서 break문을 만나지 못한다면 무한루프를 돌게 된다.
  • 숫자키로 만들 수 있는 수인지 판단하기 위해 int를 String형으로 바꾸고 contains 함수를 사용했는데...(그래서 다른 사람들의 코드보다 시간효율에서 좋지 않았다) 숫자키 배열(길이가 10)을 만들고 해당 인덱스(숫자키)에 0(누를 수 없음) or 1(누를 수 있음)로 표시해두고 [n%10]으로 해당 자리의 숫자를 누를 수 있는지 판단했다면 효율이 더 좋았을 거 같다.

📌 코드

package Baekjoon;

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

public class BOJ1107 {
  /**
   * 고장난 숫자키를 제외하고 정상적인 숫자키로 목표 숫자와 가장 가까운 수를 만든다
   * 몇 자리 수인지 확인 -> 버튼 누르는 횟수 카운트
   * +나 - 버튼을 몇 번 누르는지 확인 -> 카운트
   */

  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String n = br.readLine();
    int nNum = Integer.parseInt(n);
    int m = Integer.parseInt(br.readLine());
    String[] error = new String[m];
    // m이 0일 때는 예외처리
    if(m > 0){
      StringTokenizer st = new StringTokenizer(br.readLine());
      for(int i = 0; i < m; i++){
        error[i] = st.nextToken();
      }
    }
    else{
      System.out.println(Math.min(n.length(), Math.abs(nNum-100)));
      return;
    }

    int plus, minus;
    int cnt = 0;
    boolean numPadPlus = false;
    boolean numPadMinus = false;
    int answer = 0;
    // 반복을 멈춰야할 때 : +, -로 n이 만들어졌을 때, +,-로 만들 수 있는 수를 찾았을 때
    while(true){
      // 목표 숫자에서 + or - 를 누른 횟수를 더하거나 뺀 수
      plus = nNum + cnt;
      minus = Math.max(nNum - cnt, 0);
      // 현재 수를 숫자 패드로 만들 수 있는지 체크
      for(int i = 0; i < m; i++){
        if(Integer.toString(plus).contains(error[i])){
            numPadPlus = false;
            break;
        }
        else{
          numPadPlus = true;
        }
      }
      // minus 숫자 체크
      for(int i = 0; i < m; i++){
        if(Integer.toString(minus).contains(error[i])){
          numPadMinus = false;
          break;
        }
        else{
          numPadMinus = true;
        }
      }
      // 숫자 패드로의 이동이 빠른지 +-버튼으로의 이동이 빠른지 체크
      int pl = 500000;
      int mi = 500000;
      if(numPadPlus || numPadMinus){
        if(numPadPlus){
          pl = Math.min(Integer.toString(plus).length() + cnt , Math.abs(nNum-100));
        }
        if(numPadMinus){
          mi = Math.min(Integer.toString(minus).length() + cnt,  Math.abs(nNum-100));
        }
        answer = Math.min(pl, mi);
        break;
      }
      if(plus == 100 || minus == 100){
        answer = cnt;
        break;
      }
      cnt++;
    }
    System.out.println(answer);
  }
}
profile
step by step...my devlog

0개의 댓글