백준 1107 : 리모컨

혀니앤·2021년 10월 25일
0

C++ 알고리즘

목록 보기
83/118

https://www.acmicpc.net/problem/1107

1. 접근

  • 이용할 수 있는 버튼의 개수는 10개(0~9)로 한정되어 있다.

  • 가장 근사한 값을 버튼으로 누르고, +/-로 이동해야 한다.
    => 가장 근사한 값은 무엇일까?
    => 내가 이동하려는 값과 최종 채널 값의 차의 절댓값이 가장 작아야 한다.

  • 따라서 세 가지 값을 구하고, 비교하여 가장 작은 값을 택했다.

  1. 그냥 100번 채널에서 +/-로만 이동한다. (|n-100|의 값을 가짐)
  2. 원하는 채널 n에서 아래로 내려가면서 탐색한다.
  3. 원하는 채널 n에서 위로 올라가면서 탐색한다.
  • 이때, 최솟값을 택하기 때문에, 더 작은 값을 넘어서게되면 반복문을 종료한다.

2. 나의 풀이

#include <iostream>
#include <cstring>
using namespace std;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int n, m;
	bool btn[11];
	char channel[7];

	cin >> n >> m;

	int num = 0;
	memset(btn, true, 10);
	for (int i = 0; i < m; i++) { //0~9까지의 bool 배열에서 버튼이 고장이면 false 처리
		cin >> num;
		btn[num%10] = false;
	}

	int count = 0;
	int now = n;
	int ret = 0;
	bool IsBreak=false;

	if (n >= 100)	ret = n - 100; //가장 먼저 |n-100| 값을 넣어준다
	else ret =(n - 100) * (-1);

	for(int i=1;;i++){ //아래로 내려가면서 탐색
		while (1) {
			if (btn[now % 10]) {
				now /= 10;
				count++;
				if (now == 0) { 
					IsBreak = true;
					break;
				}
			}
			else break;
		}
		if (IsBreak) {
			ret = min(ret,count); //숫자를 다 만들 수 있다면 최솟값을 넣고 종료
			break;
		}
		if (i > n)	break; //값이 n보다도 커지면(직접 움직이는 것보다 비효율적이면) 종료
		now = n - i;
		count = i;
	}
	
	
	now = n;
	count = 0;
	IsBreak = false;
	for (int i = 1;; i++) { //위로 올라가면서 탐색
		while (1) {
			if (btn[now % 10]) {
				now /= 10;
				count++;
				if (now == 0) {
					IsBreak = true;
					break;
				}
			}
			else break;
		}
		if (IsBreak) {
			ret = min(ret, count);
			break;
		}
		if (i > ret)	break;
		now = n +i;
		count = i;
	}

	cout << ret << "\n";

	return 0;
}

3. 다른 사람의 풀이

Brute Force 문제라고 해서, 모든 값을 다 넣어서 구하는 알고리즘이다.
시간은 오래걸리더라도 코드상에서 더 간결하게 나타낼 수 있다고 한다.
채널 이동값이 원하는 값보다 위에 있을지, 아래에 있을지 모르기 때문에
천장 최댓값까지 하나씩 다 구해보면서 답을 구한다.

https://yjios.tistory.com/8

이런 문제는 더 나은 답이 어떤 것인지 잘 모르겠다..
어차피 같은 값이 나올거라면 간결한 코드가 더 좋아보이긴 한다.

profile
일단 시작하기

0개의 댓글