본문 바로가기
알고리즘 문제/SW Expert Academy

[Python] 1240. [S/W 문제해결 응용] 1일차 - 단순 2진 암호코드

by .tistory.com/ 2021. 9. 29.

# 링크

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV15FZuqAL4CFAYD&categoryId=AV15FZuqAL4CFAYD&categoryType=CODE&problemTitle=1240&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


# 접근

  • 똑같은 암호코드가 여러 줄 세로로 입력 되는 것은 큰 의미가 없습니다
  • 각 테스트케이스별로, 처음 1이 들어있는 행을 암호코드로 지정합니다
  • 우연히도, 0부터 9까지 각 코드를 구성하는 숫자는 1로 끝납니다
  • 따라서 모든 코드를 뒤에서부터 읽었을 때 가장 먼저 등장하는 1은 암호코드의 끝입니다
  • 암호코드는 검증코드를 포함한 8개의 코드로 되어있으며, 각 코드는 7개의 숫자를 가지고 있습니다
  • 가장 뒤에 있는 1이 코드의 끝이고, 그 1과 1의 앞쪽 55개 숫자가 암호코드가 됩니다
  • 찾은 암호코드의 숫자들을 7개씩 끊어서 코드가 정상인지 검증하고
  • 검증된 코드일 경우 코드의 모든 숫자를 더한 값을 출력, 그렇지 않을 경우 0을 출력합니다

# 코드

T = int(input())

password = [
    [0, 0, 0, 1, 1, 0, 1], # 0
    [0, 0, 1, 1, 0, 0, 1], # 1
    [0, 0, 1, 0, 0, 1, 1], # 2
    [0, 1, 1, 1, 1, 0, 1], # 3
    [0, 1, 0, 0, 0, 1, 1], # 4
    [0, 1, 1, 0, 0, 0, 1], # 5
    [0, 1, 0, 1, 1, 1, 1], # 6
    [0, 1, 1, 1, 0, 1, 1], # 7
    [0, 1, 1, 0, 1, 1, 1], # 8
    [0, 0, 0, 1, 0, 1, 1], # 9
]

for t in range(1, T+1):
    N, M = map(int, input().split())
    arr = []
    for n in range(N):
        tmp = input()
        if '1' in tmp: # 1이 있는 코드가 입력이 되면 시작이다
            # 하지만 나머지 줄도 입력 받아야 하기 때문에 for문을 break하지는 않는다
            if not arr: # 중복되는 코드가 여러줄 있지만, 하나만 있으면 된다
                arr = list(map(int, tmp))

    idx = 0
    for i in range(len(arr)-1, -1, -1):
        if arr[i]: # 모든 코드의 맨 뒤에 1이 있다
            idx = i # 뒤에서부터 시작해서, 처음 1이 등장하는 인덱스가, 코드의 끝이다
            break # 인덱스만 찾고 종료

    code = [] # 코드의 맨 끝 인덱스의 앞 55개 숫자를 받을 리스트
    for i in range(idx-55, idx, 7): # 각 코드의 숫자는 7칸씩
        code.append(password.index(arr[i:i+7])) # 숫자를 7개씩 슬라이싱
        # 만들어둔 password리스트에서 일치하는 인덱스를 가져온다

    odd = 0 # 홀수자리 숫자들을 더할 값
    even = 0 # 짝수자리 숫자들을 더할 값
    check = code[7] # 검증할 숫자는 code의 맨 뒤 숫자

    for i in range(0, len(code), 2): # 0번째부터 스텝을 2를 줘서 홀수자리 숫자들을 더함
        odd += code[i]
    for i in range(1, len(code)-1, 2): # 짝수는 1번째부터 스텝 2씩
        # len(code)에 -1을 해줘야, 짝수자리 숫자 3개만 더할 수 있음
        # 4번째 짝수자리는 암호를 검증할 숫자
        even += code[i]

    result = 0 # 유효한 코드이면 아래에서 값을 바꿔 줄 것이고
    # 그렇지 않으면 그대로 0을 출력
    if ((odd * 3) + even + check) % 10 == 0: # 유효한 코드이면
        result = sum(code) # 코드의 숫자들을 전부 더한 값을 result에 저장

    print('#{} {}'.format(t, result)) # 출력

# 정리

  • 여태 풀은 알고리즘 문제들 중, 가장 그 설명이 길었던 문제였습니다
  • 동시에 제한시간도 30초나 되는 문제는 처음이었습니다
  • 하지만 의외로 문제는 적당한 난이도였습니다
  • 시간을 길게 잡고 차근차근 읽으면서 하나하나 해결하는 방법이 적합한 것 같습니다
  • 똑같은 코드가 세로로 여러줄 입력이 되서 조금 혼란스러웠습니다
  • 문제에 0~9까지 밑에 1:2:1:3 같은, 어디에 써야할 지 모르겠는 비례식도 들어가 있었는데
  • 하지만 이내 금방 "의미없는 정보를 쳐내는 능력"을 요구하는구나 싶었습니다(파이썬 기준)

댓글