본문 바로가기

IT/Python

[백준] 17176번 암호해독기 [Python] - 아스키코드

728x90

0은 띄어쓰기, 1 - 26 범위 안의 수는 A ~ Z, 27 - 52 범위 안의 수는 a ~ z로 해석

평문을 암호화해서 주어진 암호문을 만들 수 있는지 확인하는 문제

 

더보기

문제

방금 도착한 암호문을 해독했는데, 해독에 오류가 없는지 확인해보려 한다. 해독한 문장이 암호문을 해석한 결과로 나올 수 없다면, 그 해독은 잘못된 것이다.

암호문은 0 이상 52 이하의 정수로 이루어져 있다. 0은 띄어쓰기, 1 - 26 범위 안의 수는 A ~ Z, 27 - 52 범위 안의 수는 a ~ z로 해석된다. 암호문은 띄어쓰기를 포함한 모든 철자를 이와 같이 정수로 치환한 후 순서를 무작위로 뒤섞어서 만들어졌다.

입력

첫 번째 줄에는 주어질 수열의 길이 N이 주어진다. $(1 ≤ N ≤ 100,000)$

두 번째 줄에는 암호문에 해당하는 수 N개가 띄어쓰기와 함께 주어진다.

세 번째 줄에는 평문이 주어진다. 단, 평문의 길이는 N과 같으며, 띄어쓰기로 시작하거나 끝나지 않는다.

출력

평문을 암호화해서 주어진 암호문을 만들 수 있다면 "y", 아니라면 "n"을 따옴표 없이 출력한다.

17176번: 암호해독기 $($acmicpc.net$)$


문자 = 10진

" " = 32 $($space, 빈 칸$)$

a~z = 97~122

A~Z = 65~90

 

딕셔너리로 접근

chr()를 활용해 숫자를 문자로 저장

 

dict.get$($key, *default value$)$

EC.get$($k,v$)$ 는 딕셔너리 EC에 k가 key 값으로

존재하면 EC[k]의 값을 반환하고,

없으면 EC[k] = v으로 저장하고 v를 반환한다.

import sys
sys.stdin.readline()
C = map(int, sys.stdin.readline().split())
P = sys.stdin.readline().strip()

# 아스키 코드를 활용해 chr(숫자) -> 문자로 변환
EC = {}
for c in C:
    c += [32,64,70][int(c>0)+int(c>26)]
    c = chr(c)
    # key: 문자, value: 그 문자의 개수
    EC[c] = EC.get(c, 0) + 1

k = 1
for p in P:
	# 딕셔너리에 존재하지 않는 문자가 나오거나 문자의 개수가 0인 경우 -> 암호문 x
    if p not in EC or EC[p] == 0:
        k = 0 
        break
    # 문자 개수를 하나씩 차감
    EC[p] -= 1
print(['n','y'][k])

 

리스트로 접근

ord()를 활용해 문자를 숫자로 저장

import sys
def f():
    sys.stdin.readline()
    C = map(int, sys.stdin.readline().split())
    P = sys.stdin.readline().strip()

    EC = [0] * 53
    for c in C:
        EC[c] += 1

    k = 1
    for p in P:
        if p == " ":
            t = 32
        elif p.islower():
            t = 70
        else: t = 64
        p = ord(p)
        p -= t
        EC[p] -= 1
        
    for i in range(53):
        if EC[i] < 0:
            return 'n'
    return 'y'
print(f())

 

더보기

예제 입력 1 

11
44 0 38 41 38 31 23 8 41 30 38
Hello World

예제 출력 1 

y

예제 입력 2 

5
12 3 34 52 0
apple

예제 출력 2 

n