수빈이는 TV를 보고 있다. 수빈이는 채널을 돌리려고 했지만, 버튼을 너무 세게 누르는 바람에, 일부 숫자 버튼이 고장났다.
리모컨에는 버튼이 0부터 9까지 숫자, +와 -가 있다. +를 누르면 현재 보고있는 채널에서 +1된 채널로 이동하고, -를 누르면 -1된 채널로 이동한다. 채널 0에서 -를 누른 경우에는 채널이 변하지 않고, 채널은 무한대 만큼 있다.
수빈이가 지금 이동하려고 하는 채널은 N이다. 어떤 버튼이 고장났는지 주어졌을 때, 채널 N으로 이동하기 위해서 버튼을 최소 몇 번 눌러야하는지 구하는 프로그램을 작성하시오.
수빈이가 지금 보고 있는 채널은 100번이다.
첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼이 주어지며, 같은 버튼이 여러 번 주어지는 경우는 없다.
첫째 줄에 채널 N으로 이동하기 위해 버튼을 최소 몇 번 눌러야 하는지를 출력한다.
채널 N 으로 이동하기 위한 최소 cnt
를 구해야하는 문제로 리모컨 처럼 상하로 버튼을 통해
직접 조작할 수 있고 숫자 버튼을 통해 이동할 수도 있으므로 이러한 경우들에 대해 전부 구해
cnt
를 비교해야 한다. 따라서 구할 수 있는 방법은
위의 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;
}
문제를 읽고 브루트포스 문제라는 것을 빠르게 파악하는 것이 중요하고
만약 브루트포스 문제라고 인식했다면 구현을 바로 시작하면 코드가 계속 바뀌어 꼬이게 된다.
문제를 풀기 위한 조건과 방법을 정리한 뒤 그에 따라 구현하는 연습을 해보자.
와 for문을 백만 까지 돌리는건 상상도 못했네요 감사합니다!