[백] 1107 리모컨 - 뇌 고장

serotonins·2023년 7월 3일
0

Coding Q

목록 보기
16/17

그래도 기어코 혼자 풀었다 장하다 나

풀이반례2시간
OXX

처음에는 이렇게 풀고자 했다.
큰 자릿수부터 고장 안 난 숫자 버튼으로 눌러지면 누르다가 안되면 가장 가까운 되는 숫자를 추가.
큰 숫자로 갔다면 뒤부터는 누를 수 있는 숫자 중 가장 작은 걸로 쭉.
작은 숫자로 갔다면 뒤부터는 누를 수 있는 숫자 중 가장 큰 걸로 쭉.

근데 큰 숫자로 갔다가 9인데 더 크려면 그 앞자리수를 올리고 그 앞도 9였다면 또 올리고 이런 거 생각하다가 많이 복잡해져서 폐기.

원하는 채널 번호에서 +, - 방향으로 더해가면서 정상 숫자버튼으로 가능하면 각각 저장.
가장 큰 자릿수부터 검사해가면서 정상 버튼으로 가능하면 넘어가고, 아니면 하나씩 방향대로 +-.

오류 깨기

  • 틀렸습니다: 고장나지 않은 == 정상 숫자버튼 집합(set)는 요소가 숫자로 되어있는데 만들 수 있는지 비교할 때 str로 들어가 있었음
    ❗ int ↔ str ↔ 집합 이렇게 쓸 때 type == 형! 주의하기

  • 시간 초과: while문 벗어나는 조건에서 채널 번호가 0~무한대까지 있다고는 하지만 원하는 채널이 500000까지기 때문에 최대는 500000-100인 499900이므로 연산해볼 숫자는 999900까지다. 작은 것도 0 포함! 그 밑으로 내려가면 멈춰야됨.
    ❗ while 쓸 때 break 해줄 조건문 신경쓰기, 범위 신경쓰기
def mapinput(): return map(int, input().split())

want = int(input())
g = int(input())
if g != 0: gozang = set(mapinput())
else: gozang = set()

now = 100

answer = 0
maxi = abs(want - now)
poss = set(i for i in range(10)) - gozang

def canmake(num):
    if len(set(map(int, str(num))) - poss) == 0: return True
    else: return False
def jaritsu(num): return len(str(num))

if maxi == 0: answer = 0
elif g == 10: answer = maxi
elif canmake(want): answer = min(len(str(want)), maxi)
else:
    makeup, makedown = want+1, want-1
    upans, downans = 500001, 500001
    while True:
        if upans == 500001: # 첨이고 범위내다
            if canmake(makeup):
                upans = jaritsu(makeup) + abs(makeup - want)
            else:
                for i, s in enumerate(str(makeup)):
                    if int(s) not in poss:
                        key = 10 ** (jaritsu(makeup)-1-i)
                        makeup = makeup // key * key + key
                        break

        if downans == 500001 and makedown >= 0:
            if canmake(makedown):
                downans = jaritsu(makedown) + abs(makedown - want)
            else:
                for i, s in enumerate(str(makedown)):
                    if int(s) not in poss:
                        key = 10 ** (jaritsu(makedown) - 1 - i)
                        makedown = makedown // key * key - 1
                        break

        if (makeup > 999999 or upans != 500001) and (makedown <= 0 or downans != 500001):
            answer = min(upans, downans, maxi)
            break


print(answer)

0개의 댓글