Algorithms/Problems
[BOJ_1107][Brute_Force]리모컨
esmJK
2021. 8. 27. 16:45
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, - 버튼을 이용해
특정 채널로 이동하려고 할 때 망가지지 않은 버튼을 이용해 이동하려면 최소 몇 번 버튼을 눌러야 하는지 계산하는 문제입니다. 유의해야 할 점은, 목표 채널로 이동하기 위해 숫자를 누르지 않는 것이 빠를 수 있다는 점입니다. 또한, 목표채널 N이 어디에 존재할 지 모르므로 뺄셈 연산 후 절대값을 취해줘야 함을 잊지 말아야 합니다.
1. 모든 번호를 Brute Force 로 탐색(0 에서 500000까지의 N 이 존재하지만, 이동할 수 있는 채널의 제한은 없으므로 1000000 까지의 채널을 탐색하도록 합니다. 망가진 버튼이 무엇인가에 따라 N 범위를 벗어난 채널에서 이동하는 것이 더 빠를 수 있습니다.
2. 고른 채널을 숫자를 눌러 이동할 수 있는지를 확인합니다.
3. 고른 채널에서 몇 번 더 +, - 버튼을 눌러 원하는 채널로 이동할지 확인합니다. 간단한 뺄셈 연산입니다.
정답
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
vector<int> br;
bool broken[10];
// check if the chosen number can be used
// returning len 0 means that only + or - will be used
int possible(int num) {
int numcpy = num;
if (num == 0) {
if (broken[0]) return 0;
else return 1;
}
int len = 0;
while (numcpy > 0) {
if (broken[numcpy % 10]) return 0;
len++;
numcpy /= 10;
}
return len;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
//freopen("input.txt", "r", stdin);
int m, n;
cin >> n >> m;
for (int i = 0; i < m; i++) {
int tmp;
cin >> tmp;
broken[tmp] = true;
} // input
// Brute Force through each possible number
int ans = abs(n - 100);
for (int i = 0; i <= 1000000; i++) {
int num = i;
int len = possible(num);
if (len > 0) {
int press = abs(num - n);
if (len + press < ans) ans = len + press;
}
}
cout << ans << '\n';
return 0;
}
오답
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
vector<int> br;
int m, n;
bool broken[10];
int countpress(int pick) {
// count the presses for final pick
int pickcpy = pick;
int press = 0;
if (abs(n - pickcpy) < abs(100 - pickcpy)) {
while (pickcpy) {
pickcpy /= 10;
press++;
}
}
press += abs(n - pick);
return press;
}
bool check(int num) {
int cpy = num;
// guessed number 0
if (num == 0) {
if (broken[num] == true) return false;
else return true;
}
// not 0
while (cpy > 0) {
if (broken[cpy % 10] == true) {
return false;
}
cpy /= 10;
}
return true;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
//freopen("input.txt", "r", stdin);
cin >> n >> m;
for (int i = 0; i < m; i++) {
int tmp;
cin >> tmp;
broken[tmp] = true;
}
// pick c to move to
if (n == 100) {
cout << 0 << '\n';
return 0;
}
int pick = 100;
int ans = abs(n - 100);
int anscpy = ans;
for (int num = 0; num < 1000000; num++){
bool possible = true;
possible = check(num);
if (possible == false) continue;
if (abs(num - n) < anscpy) {
pick = num;
anscpy = abs(num - n);
}
}
//cout << pick << '\n';
// counts number of presses
int res = min(ans, countpress(pick));
cout << res << '\n';
return 0;
}