컴퓨터 공학 기초/알고리즘 (브루트포스)
백준 (1107) 리모컨
JongSeok_12
2020. 7. 9. 15:00
https://www.acmicpc.net/problem/1107
1107번: 리모컨
첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼��
www.acmicpc.net
로직
2가지 경우의 수를 구해야 한다.
1. 100 에서 n의 값을 뺀 절대값
2. DFS를 사용하여 고장난 리모컨 채널을 제외환 모든 채널의 경우의 수를 만들면서 n과 모든 채널의 값을 뺀 절대값
1번과 2번의 최소 절대값을 비교하여 작은 수가 정답이 된다.
소스
#include <iostream>
#include<stdio.h>
using namespace std;
int n;
int nSize;
int resCnt;
int hres;
int minn = 10000000;
int used[10];
int flag = 0;
// n이 몇자리인지 구하는 함수
int getSize(int n){
int cnt = 0;
while (1){
if (n <= 0){
break;
}
n = n / 10;
++cnt;
}
return cnt;
}
// rcnt는 채널의 자리수를 나타내며 res는 채널의 번호
void dfs(int res, int rcnt){
if (rcnt > nSize+1){
// 현재 채널이 1000이고 n이 999일때 자리수 까지만 가서 반환한다면
// 1000 - 1 = 999인 경우는 탐색하지 못하므로 +1한 자리수까지 포함시킨다.
return;
}
if (rcnt > 0){
if (n != res){
int sum = abs(n - res);
resCnt = rcnt + sum;
if (minn > resCnt) minn = resCnt;
}
if (n == res){
resCnt = rcnt;
if (minn > resCnt) minn = resCnt;
}
}
for (int i = 0; i < 10; ++i){
if (used[i] == 0){
dfs(res * 10 + i, rcnt + 1);
}
}
}
int main(){
freopen_s(new FILE*, "tes.text", "r", stdin);
cin >> n;
int ncnt;
cin >> ncnt;
for (int i = 0; i < ncnt; ++i){
int idx;
cin >> idx;
used[idx] = 1;
}
if (n == 100){
printf("0");
return 0;
}
else{
hres = abs(n - 100);
}
nSize = getSize(n);
dfs(0, 0);
if (minn > hres){
printf("%d", hres);
}
else{
printf("%d", minn);
}
}