CS/알고리즘_문제풀이(파이썬)

리모컨

Jedy_Kim 2021. 7. 15. 18:56
728x90

문제

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

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

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

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

입력

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

출력

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

예제 입력 1

5457

3

6 7 8

예제 출력 1 

6

예제 입력 2 

100

5

0 1 2 3 4

예제 출력 2 

0

예제 입력 3 

500000

8

0 2 3 4 6 7 8 9

예제 출력 3 

11117

 

# 코드 : 어느 부분이 틀렸을까?

# 원인

'''

9번 버튼만 정상이고 
1000 가는 경우도
999찍고 올리면 되는 경우 

1번 버튼만 정상이고
 999로 가는 경우도 
1111찍고 내려가는게 빠름

 

즉 기저 조건에서 이미 자릿수를 고정 시켜버렸기에 구조 자체가 결함이였던 것이다.

'''

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import sys 
 
def getResult(x):
  global n, visited, getVal, n_len, result, getRes, flag
  # 정의 : 가능한 모든 번호를 배합하여 목표하는 근사치를 구한다.
  # x는 각 자릿수의 인덱스를 의미한다.
  # 기저 조건 : 인덱스 x가 목표하는 자릿수(길이)보다 같거나 커질경우.
  if flag: return #찾은 값이 근사치와 일치하는 경우 더 이상 실행하지 않는다.
  if x >= n_len:        
    myVal = ''
    for i in result: 
      myVal += str(i) 
 
    if int(myVal) == n: #찾은 값이 근사치와 일치하는 경우
      flag = True
      return
    
    newVal = abs(n-int(myVal))
    if newVal < getVal:
      getVal = newVal
      getRes = int(myVal)
    
  else:
    for i in range(9-1-1):
      if visited[i] == -1: continue # 못쓰는 값인 경우 
      if visited[i] != -1
        result[x]  = i
        getResult(x+1
   
# 설계 
# 1. 재귀를 통해 주어진 값과 일치하거나 가장 근사한 값을 찾아낸다.
# 2. 
if __name__ == "__main__":
  input = sys.stdin.readline
  
  n       = input().strip()
  n_len   = len(n)
  n       = int(n)  
  
  result  = [0]*n_len 
  visited = [False for _ in range(10)]
  getVal  = int(1e9# 브루트 포스를 통해 얻은 값이 가장 근사하거나 일치한 값을 찾는다.
  getRes  = 0
  flag    = False
 
  # 1. 현재 있는 100번 채널에서 + 혹은 -만 눌러서 이동하기
  anotherCase = abs(n - 100
  m       = int(input())
  if m > 0:
    arr   = list(map(int, input().split()))  
    # 사용 못 하는 번호 : -1
    for i in arr:
      visited[i] = -1  
  
 
  # 답 
  if n == 100
    print(0)
  else:
    getResult(0
    if flag:
      print(min(anotherCase, n_len))
    else
      print(min(anotherCase, (getVal + n_len))) 
cs

 

# 코드 : 접근법에 대한부분을 정리해서 올릴 예정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import sys
 
if __name__ == "__main__":
    input = sys.stdin.readline
    n     = int(input())
    m     = int(input())
    btns  = {str(i) for i in range(10)} 
    
    if m>0:
        btns -= set(map(str, input().split()))
    
    cur_chan = 100
    
    min_cnt = abs(n-cur_chan)
    
    for channel in range(1000000):
        for j in range(len(str(channel))):
            if str(channel)[j] not in btns:
                break
            elif len(str(channel))-1 == j:
                min_cnt = min(min_cnt, abs(channel-n)+len(str(channel)))
    
    print(min_cnt)
cs

 

반응형

'CS > 알고리즘_문제풀이(파이썬)' 카테고리의 다른 글

팰린드롬 만들기  (0) 2021.07.16
카잉 달력  (0) 2021.07.16
제곱수의 합  (0) 2021.07.14
버튼 누르기  (0) 2021.07.14
카드 놀이  (0) 2021.07.14