본문 바로가기

2024 코딩테스트 스터디

[7주_6일차] 백준-1107 리모컨(Python)

문제

수빈이는 TV를 보고 있다. 수빈이는 채널을 돌리려고 했지만, 버튼을 너무 세게 누르는 바람에, 일부 숫자 버튼이 고장났다.

리모컨에는 버튼이 0부터 9까지 숫자, +와 -가 있다. +를 누르면 현재 보고있는 채널에서 +1된 채널로 이동하고, -를 누르면 -1된 채널로 이동한다. 채널 0에서 -를 누른 경우에는 채널이 변하지 않고, 채널은 무한대 만큼 있다.

수빈이가 지금 이동하려고 하는 채널은 N이다. 어떤 버튼이 고장났는지 주어졌을 때, 채널 N으로 이동하기 위해서 버튼을 최소 몇 번 눌러야하는지 구하는 프로그램을 작성하시오.

수빈이가 지금 보고 있는 채널은 100번이다.

입력

첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼이 주어지며, 같은 버튼이 여러 번 주어지는 경우는 없다.

출력

첫째 줄에 채널 N으로 이동하기 위해 버튼을 최소 몇 번 눌러야 하는지를 출력한다.

 

 

<코드>

def is_possible_channel(channel, broken_buttons): #고장나지 않은 버튼으로 이동 가능한지 확인
    for ch in str(channel): #채널번호를 문자열로 변환해 비교
        if ch in broken_buttons: #하나라도 고장난 버튼이 있으면 False
            return False
    return True

def find_min_presses(target_channel, broken_buttons): #최소이동횟수 찾는 함수
    min_presses = abs(target_channel - 100)  # + or - only
    for channel in range(1000000):  # 조건보다 큰 범위 내에서 동작하도록 설정
        if is_possible_channel(channel, broken_buttons):
            presses = len(str(channel)) + abs(channel - target_channel)
            min_presses = min(min_presses, presses)
    return min_presses

# Input
N = int(input())
M = int(input())
if M > 0:
    broken_buttons = set(input().split()) #세트로 저장
else:
    broken_buttons = set()

print(find_min_presses(N, broken_buttons))

 

 

<풀이과정>

1. is_possible_channel 함수

특정 채널 번호를 주어진 고장난 버튼을 사용하지 않고 만들 수 있는지 확인

  • channel을 문자열로 변환하여 각 자리 수를 확인
  • 각 자리 수가 broken_buttons (고장난 버튼 목록)에 있는지 검사
  • 만약 하나라도 고장난 버튼이 포함되면 False를 반환하고, 그렇지 않으면 True 반환

2. find_min_presses 함수

목표 채널로 이동하는 데 필요한 최소 버튼 클릭 수 계산

 

  • 기본 값 설정:
    • min_presses를 현재 채널 (100)에서 목표 채널 (target_channel)로 이동하는 데 필요한 +와 - 버튼만을 사용한 최소 횟수로 초기화 -> abs(target_channel - 100)
  • 모든 채널 확인:
    • 가능한 모든 채널 번호 (0에서 999,999까지) 확인(최대 채널 번호인 500,000을 넘는 범위로 설정)
  • 고장나지 않은 버튼으로 만들 수 있는 채널 확인:
    • is_possible_channel(channel, broken_buttons)를 사용하여 채널 번호를 고장나지 않은 버튼만으로 만들 수 있는지 확인
  • 버튼 클릭 수 계산:
    • 가능한 채널 번호가 주어지면, 그 채널로 이동하기 위해 필요한 클릭 수 계산
    • 숫자 버튼을 눌러 채널 번호를 입력한 후 (len(str(channel))), 그 채널에서 목표 채널로 이동하기 위해 필요한 +와 - 버튼 클릭 수 (abs(channel - target_channel)) 합
  • 최소 클릭 수 업데이트:
    • 계산된 클릭 수가 현재 min_presses보다 작으면, min_presses를 업데이트

3. 입출력

 

  • 고장난 버튼이 있으면, 세트로 저장
  • find_min_presses 함수 호출해 목표 채널로 이동하는 데 필요한 최소 버튼 클릭 수를 계산 후 출력