개발 이야기/알고리즘 및 코테 준비

[Softeer][21년 재직자 대회 예선] 전광판 문제

혁진 2024. 9. 4. 22:07

문제

 전광판은 최대 다섯 자리의 자연수만을 표시할 수 있도록, 아래와 같이 육각형 모양의 전구 7×5=35개로 구성되어 있다.

각각의 전구에는 스위치가 달려 있다. 전구에 달려 있는 스위치를 누를 때, 그 전구가 켜져 있었다면 꺼지고, 그 전구가 꺼져 있었다면 켜진다.

 

지금 전광판에 자연수 A가 표시되어 있는데, 유가가 변동됨에 따라 전광판에 표시된 자연수를 B로 바꿔야 한다. 이러한 목표를 달성하기 위해 스위치를 최소 몇 번 눌러야 하는지를 구하는 프로그램을 작성하라.

 

제약조건

하나의 입력에서 1개 이상 1000개 이하의 테스트 케이스를 해결해야 한다.

A와 B는 한 자리 이상 다섯 자리 이하의 자연수이다.

A와 B는 숫자 0으로 시작하지 않는다.

A와 B는 서로 다르다.

입력형식

첫 번째 줄에 해결할 테스트 케이스의 수 T가 주어진다.

다음 T개의 줄에는 한 줄에 테스트 케이스 하나씩이 주어진다. 각각의 줄에는 두 자연수 A와 B가 공백 하나를 사이로 두고 주어진다.

출력형식

각각의 테스트 케이스마다 순서대로, 스위치를 눌러야 하는 최소 횟수를 한 줄에 하나씩 출력한다.

 

입력예제1

2 1 2 9881 10724

출력예제1

5 11

입력예제2

2 111 11 11 11111

출력예제2

2 6

 

풀이

처음 문제를 봤을 때 스위치 변환 개수를 알기위해서는 각 숫자별(1~9)별 어떤 스위치를 켜고 끄는지 기록해야한다고 생각하여 8칸짜리 list에 1혹은0으로 표시하고자 생각했다. 

 

이를 위해 숫자 list를 만들려면 9개 list에 내부에 list가 또 있는 형태를 만들어야하는데 이보다 이진법을 이용하기로 했다. 

즉 7자리의 이진수로 표현하고 이를 num_dict에 이용한다. 

 

테스트 케이스 T에 관해 한줄 한줄 테스트 케이스가 주어진다. 또한 A와 B는 한자리 이상 5자리 이하 자연수임으로 

만일 1이 주어지는 경우 00001로 변경해야한다. 

 

가장 중요한건 새롭게 추가된 0 즉, 1이 들어오면 00001인데 이때 추가된 0은 불이 모두 꺼진 상태이다.

 

이를 위해 .zfill()이 아닌 rjust를 이용한다. 

 

마지막으로 두 숫자에 관해서 bulb가 몇개가 변했는가는

0*1 = 1혹은 1*0 =1 인 경우임으로 XOR연산을 적용한다. 

 

그럼으로 코드는 아래와 같을 것이다. 

import sys

num_bulb = {
    '0': 0b1111110,  # 0
    '1': 0b0110000,  # 1
    '2': 0b1101101,  # 2
    '3': 0b1111001,  # 3
    '4': 0b0110011,  # 4
    '5': 0b1011011,  # 5
    '6': 0b1011111,  # 6
    '7': 0b1110010,  # 7
    '8': 0b1111111,  # 8
    '9': 0b1111011,  # 9
    ' ': 0b0000000   # fill
}
    
T = int(input())        
for _ in range(T):
    a, b = input().split()
    a = str(a).rjust(5, " ")
    b = str(b).rjust(5, " ")
    switch_count = 0
    
    for i in range(5):
        digit_a = a[i]
        digit_b = b[i]
        digit_a = num_bulb[digit_a]
        digit_b = num_bulb[digit_b]
        switch_count  += bin(digit_a ^ digit_b).count('1')
        
    print(switch_count)