백준 1107 : 리모컨
난이도 : 골드 5
시간 : 1시간 소요
문제
https://www.acmicpc.net/problem/1107
1107번: 리모컨
첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼
www.acmicpc.net

풀이 과정
이동하려는 채널을 기준으로 모든 경우를 탐색하면 되는 문제이다.
abs() 이나 to_string()을 사용하지 않고 하려니 코드가 많이 지저분해지고, 구석구석 오류가 좀 생겼다.
그래서 반례를 찾느라 40분은 쓴 것 같다.
해결 과정은 간단하다.
1. 현재 채널에 고장난 버튼이 있는지 확인
2. 없다면 현재 채널의 자릿수와 + 또는 - 횟수를 더한다.
3. 100부터 시작해서 + - 하는 횟수와 비교해서 최솟값 출력
솔직히 많이 지저분한 것 같다. 0부터 입력값 끝까지 탐색하는 것이 느리긴 해도 더 깔끔한 코드가 될 거 같다.
최종 코드
#include <iostream>
#include <cstring>
using namespace::std;
int N, M;
int err[11];
int cur = 100;
bool check(int n){
if(n<0){
return false;
}
int m = 1;
int t = 1;
int p = 10;
int cnt = 1;
while(1){
if(n/p != 0){
p *= 10;
cnt++;
}else{
break;
}
}
for(int i=1; i<=cnt; i++){
t = n/m;
int ch = t%10;
if(t == 0 && n>0)
break;
for(int i=0; i<M; i++){
if(ch == err[i]){
return false;
}
}
m *= 10;
}
return true;
}
int main(){
cin >> N;
cin >> M;
for(int i=0; i<M; i++){
scanf("%d", &err[i]);
}
int diff = 0;
int result = 0;
int cur_diff = 0;
if(cur > N){
cur_diff = cur - N;
}else{
cur_diff = N - cur;
}
while(1){
bool t1 = check(N-diff);
bool t2 = check(N+diff);
if(t1){
result = N-diff;
break;
}else if(t2){
result = N+diff;
break;
}else{
diff++;
}
if(cur_diff<diff){
printf("%d\n", cur_diff);
return 0;
}
}
int p = 10;
int cnt = 1;
while(1){
if(result/p != 0){
p *= 10;
cnt++;
}else{
break;
}
}
if(cur_diff < cnt + diff){
printf("%d\n", cur_diff);
return 0;
}
printf("%d\n", cnt + diff);
}

'PS' 카테고리의 다른 글
[C++] 백준 1753 - 최단경로 (0) | 2023.03.02 |
---|---|
[C++] 백준 10026 - 적록색약 (0) | 2023.03.01 |
[C++] 백준 16236 - 아기상어 (2) | 2023.03.01 |
[C++] 백준 1707 - 이분 그래프 (0) | 2023.03.01 |
[C++] 백준 2206 벽 부수고 이동하기 + 결정적 반례 (1) | 2023.02.28 |
댓글