[C++] 백준 1107번 : 리모컨

E woo·2023년 6월 20일
1

백준

목록 보기
5/18

문제


수빈이는 TV를 보고 있다. 수빈이는 채널을 돌리려고 했지만, 버튼을 너무 세게 누르는 바람에, 일부 숫자 버튼이 고장났다.

리모컨에는 버튼이 0부터 9까지 숫자, +와 -가 있다. +를 누르면 현재 보고있는 채널에서 +1된 채널로 이동하고, -를 누르면 -1된 채널로 이동한다. 채널 0에서 -를 누른 경우에는 채널이 변하지 않고, 채널은 무한대 만큼 있다.

수빈이가 지금 이동하려고 하는 채널은 N이다. 어떤 버튼이 고장났는지 주어졌을 때, 채널 N으로 이동하기 위해서 버튼을 최소 몇 번 눌러야하는지 구하는 프로그램을 작성하시오.

수빈이가 지금 보고 있는 채널은 100번이다.

입력


첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼이 주어지며, 같은 버튼이 여러 번 주어지는 경우는 없다.

출력


첫째 줄에 채널 N으로 이동하기 위해 버튼을 최소 몇 번 눌러야 하는지를 출력한다.

풀이


채널 N 으로 이동하기 위한 최소 cnt 를 구해야하는 문제로 리모컨 처럼 상하로 버튼을 통해
직접 조작할 수 있고 숫자 버튼을 통해 이동할 수도 있으므로 이러한 경우들에 대해 전부 구해
cnt 를 비교해야 한다. 따라서 구할 수 있는 방법은


  1. ch 100 번에서 +, - 를 통해 직접 움직이는 방법
  2. 버튼 조작을 통해 채널로 이동 -> 만약 해당 채널로 한번에 가지 못할 경우 +, - 로 이동

위의 2가지 방법을 통해 더 적게 움직일 수 있는 cnt 를 구한다.

코드


#include <iostream>
#include <string>

using namespace std;

int broken_btn[10] = {
    0,
};


bool btn_set(int n)
{
    string str_n = to_string(n);
    for (int i = 0; i < str_n.length(); i++)
    {
        if (broken_btn[str_n[i] - '0'] == 1)
            return false;
    }

    return true;
}

int main()
{
    int N;
    int M;
    cin >> N;
    cin >> M;

    int ch = 100;
    int ans;

    for (int i = 0; i < M; i++)
    {
        int btn_number;
        cin >> btn_number;
        broken_btn[btn_number] = 1;
    }
	
    // 1번 방법
    int cnt = abs(ch - N);
	
    // 2번 방법
    for (int i = 0; i <= 1000000; i++)
    {
        if (btn_set(i) == true)
        {
            int second_cnt = abs(N - i) + to_string(i).length();
            cnt = min(cnt, second_cnt);
        }
    }
    cout << cnt;

    return 0;
}

리뷰


문제를 읽고 브루트포스 문제라는 것을 빠르게 파악하는 것이 중요하고
만약 브루트포스 문제라고 인식했다면 구현을 바로 시작하면 코드가 계속 바뀌어 꼬이게 된다.

문제를 풀기 위한 조건과 방법을 정리한 뒤 그에 따라 구현하는 연습을 해보자.

profile
뒘벼

1개의 댓글

comment-user-thumbnail
2024년 5월 4일

와 for문을 백만 까지 돌리는건 상상도 못했네요 감사합니다!

답글 달기