[ 백준 ] 1107 / 리모컨

金弘均·2021년 9월 15일
0

Baekjoon Online Judge

목록 보기
104/228
post-thumbnail

# Appreciation

/*
 * Problem :: 1107 / 리모컨
 *
 * Kind :: Brute Force
 *
 * Insight
 * - 이동하고 싶은 채널에 가장 가까우며 숫자버튼만을 사용해서 갈 수 있는 채널을 구하는
 *   그리디한 알고리즘을 구하려다 실패했다
 *   + 999번 채널로 이동하고 싶은데 숫자 9 버튼이 고장나있다면, 위의 알고리즘은 1000번을 구해야한다
 *     근데 이제 숫자 1번 버튼도 고장났다면, 위의 알고리즘은 888번을 구해야한다
 *     근데 이제 숫자 0번 버튼도 고장났다면, 위의 알고리즘은 888번을 구해야한다
 *     고려해야될 경우의 수가 너무 많다... 알고리즘 구현 실패!
 *
 * - 그래서 그냥 다 해보기로 했다
 *   # 사실 0 <= N <= 500,000 보고 그냥 처음부터 다 해봐야지 라고 생각했어야 했다...
 *
 * Point
 * - 범위 설정을 잘해야 한다
 *   + 가고 싶은 채널이 10번인 경우와 1000번인 경우는 후보군이 될 수 있는 채널들의 범위가 다르다
 *     # 모든 숫자버튼들이 고장난 경우, 10번 채널로 이동하기
 *       -> 현재 수빈이가 보고 있는 채널이 100번이라는 사실을 고려해야한다
 *     # 가고 싶은 채널보다 위에 있는 채널에서 내려오는 경우와 아래 있는 채널에서 올라오는 경우
 *       -> 가고 싶은 채널 번호를 N 이라고 하면 범위는 일반적으로 (0, N*2) 정도 될 것이다
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <vector>

using namespace std;

#define endl '\n'

// Set up : Global Variables
bool broken[10];

// Set up : Functions Declaration
int isPossible(int ch);


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    int N; cin >> N;
    int M; cin >> M;
    /* 고장난 버튼이 있는 경우 */
    if (M > 0) {
        for (int i=0; i<M; i++) {
            int n; cin >> n;
            broken[n] = true;
        }
    }

    // Process
    int ans = abs(100 - N); /* 일단 '+', '-' 버튼으로만 움직여보기 */
    /* 확인해보아야 할 후보채널들의 범위 */
    int scope = max(2*N, 2*100); /* 이동하고자 하는 채널이 1000번인 경우와 10번인 경우
                                  * 각각의 상황에 맞게 범위를 설정 */
    for (int i=0; i<=scope; i++) {
        int r = isPossible(i);
        /* 숫자버튼만으로 i번 채널까지 이동가능하다면 */
        if (r != -1) {
            /* 답을 갱신 */
            ans = min(ans, r + abs(i - N));
        }
    }

    // Control : Output
    cout << ans << endl;
}

// Helper Functions
int isPossible(int ch)
/* 고장나지 않은 숫자버튼들을 사용해서 ch번 채널로 이동가능하면 버튼을 누른 횟수를 반환
 * 그 외 -1을 반환 */
{
    /* 0번 채널은 따로 처리 */
    if (ch == 0) {
        return (not(broken[0])) ? 1 : -1;
    }

    int clicks = 0;
    while (ch) {
        int n = ch % 10;
        if (broken[n]) return -1;
        clicks++;
        ch /= 10;
    }

    return clicks;
}
profile
이런 미친 게임을 봤나! - 옥냥이

0개의 댓글