SWEA 1240単純バイナリパスワード


マイコード
import sys

sys.stdin = open("단순 2진 암호코드.txt")

# 패턴이 키 값이 되는 형태
pattern_dic = {
    "0001101": 0,
    "0011001": 1,
    "0010011": 2,
    "0111101": 3,
    "0100011": 4,
    "0110001": 5,
    "0101111": 6,
    "0111011": 7,
    "0110111": 8,
    "0001011": 9,
}

T = int(input())

for tc in range(1, T + 1):
    # N: 배열의 세로 크기
    # M: 배열의 가로 크기
    N, M = map(int, input().split())
    ARR = [input() for _ in range(N)]

    # 배열을 탐색하며 1이 있는지 확인합니다.
    start_r = -1
    for i in range(N):
        if "1" in ARR[i]:
            start_r = i
            break
    # 7줄만 남기고 배열을 잘라내자
    ARR = ARR[start_r:start_r + 7]
    # 열 잘라내기
    # 뒤에서부터 탐색
    end_c = M
    for i in range(M - 1, -1, -1):
        # 모든 암호가 1로 끝나기 때문에, 맨 뒤를 확인한다.
        if ARR[0][i] == "1":
            end_c = i
            break
    # 우리가 찾아야 탐색해야 할 문자열
    secret_text = ARR[0][end_c - 55:end_c + 1]

    solve_list = []
    for i in range(0, 56, 7):
        temp_secret = secret_text[i:i + 7]
        solve_list.append(pattern_dic[temp_secret])

    # 검증 과정
    confirm_number = 0
    for i in range(8):
        if (i + 1) % 2:
            confirm_number += int(solve_list[i]) * 3
        else:
            confirm_number += int(solve_list[i])

    # 검증 실패 시 0 출력
    result = 0
    if confirm_number % 10 == 0:
        result = sum(solve_list)

    print(f"#{tc} {result}")
方法

  • 暗号モードに対応する値に対応するため、ディックシャナが発表された.
    キー値でパスワード文字列を設定したり、復号化された数値で設定したりできますが、この問題は復号化中に行われるので、パスワードモードをキー値に設定します.

  • 不要な文字列がカットされました.

  • いいですよ.
    同じ暗号文字列は数行に存在し、復号のために1行しか知らないので、暗号文字列にのみ含まれる1が見つかり、その行だけが残っています.

  • ねつ
    パスワードモードはゼロからなので、前から探すのは難しいかもしれないと思います.
    よく見ると、すべてのパスワードモードが1で終わり、後ろのカットラインから1に移動することで、実際のパスワードモードの位置を見つけることができます.
  • 他のイケメンのコードを知る
    decryption = {
        '0001101': 0,
        '0011001': 1,
        '0010011': 2,
        '0111101': 3,
        '0100011': 4,
        '0110001': 5,
        '0101111': 6,
        '0111011': 7,
        '0110111': 8,
        '0001011': 9
    }
    
    T = int(input())
    
    for tc in range(1, T + 1):
        N, M = map(int, input().split())
        arr = [input() for _ in range(N)]
        code = ''
        for i in range(N):
            for j in range(M -1, -1, -1):
                if arr[i][j] == '1':
                    code += arr[i][j - 55 : j + 1]
        dcode= []
        start, end = 0, 7
        for i in range(8):
            dcode.append(decryption[code[start:end]])
            start += 7
            end += 7
     
        if ((dcode[0] + dcode[2] + dcode[4] + dcode[6]) * 3 + dcode[1] + dcode[3] + dcode[5] + dcode[7]) % 10 == 0:
            print('#{} {}'.format(tc, sum(dcode)))
        else:
            print('#{} {}'.format(tc, 0))
  • の今回のコードを作成する過程で、変数名をどう言うかを考えていたが、このコードで答えが見つかった.
    code - decode - decryption
    これで宣言変数が確認されやすくなります.
  • 暗号パターンの位置(列)を見つけるために,後から探索したことが確認できる.
  • T = int(input())
    
    number = [
    [0,0,0,1,1,0,1],
    [0,0,1,1,0,0,1],
    [0,0,1,0,0,1,1],
    [0,1,1,1,1,0,1],
    [0,1,0,0,0,1,1],
    [0,1,1,0,0,0,1],
    [0,1,0,1,1,1,1],
    [0,1,1,1,0,1,1],
    [0,1,1,0,1,1,1],
    [0,0,0,1,0,1,1]
    ]
     
     
    for tc in range(1,T+1):
        N, M = map(int, input().split())
        arr = []
        # 행을 받아와서 1이 있는 행의 인덱스값 추출
        for i in range(N):
            arr += [list(map(int, ' '.join(input()).split()))]
            if 1 in arr[i]:
                ob_i = i
     
        # 사용할 행만 따로 뽑기
        data = list(arr[ob_i])
     
        # 역순으로 방문하여 1이되는 열 인덱스 파악
        for i in range(M-1,-1,-1):
            if data[i] == 1:
                ob_i = i
                break
     
     
        # 숫자 섹션을 나누어서 암호숫자와 대비, 숫자 찾기
        num_res = []
        data = data[ob_i-55:ob_i+1] # 해당 인덱스 추출
        for i in range(0,56,7):
            section = data[i:i+7] # 섹션 뽑기
            for j in range(len(number)): # 암호숫자 비교
                cnt = 0
                for k in range(7):
                    if section[k] == number[j][k]:
                        cnt += 1
                if cnt == 7: # 완전히 일치하면 저장
                    num_res += [j]
                    break
     
        # 암호 유효성 판별
        temp1 = 0 # 홀수자리 합
        temp2 = 0 # 짝수자리 합
        for i in range(7):
            if i % 2:
                temp2 += num_res[i]
            else:
                temp1 += num_res[i]
        if (temp1*3+temp2+num_res[7]) % 10 or not (temp1+temp2+num_res[7]):
            res = 0
        else:
            res = temp1+temp2+num_res[7]
        print('#{} {}'.format(tc,res))

  • 列を逆順序で参照する方法は同じです.

  • 暗号パターンを説明するために,二重配列を宣言すると相違が認められる.
    並べられているので、暗号数字を比較する過程で繰り返し使う文章が多く、個人的にはディック・シャナリーの方が近い方が清潔だと思いますが、優越する必要はありません.