# 맨 앞 0까지 비율 하면 복잡해서 빼줌
ratio = {
(2, 1, 1): 0,
(2, 2, 1): 1,
(1, 2, 2): 2,
(4, 1, 1): 3,
(1, 3, 2): 4,
(2, 3, 1): 5,
(1, 1, 4): 6,
(3, 1, 2): 7,
(2, 1, 3): 8,
(1, 1, 2): 9,
}
tc = int(input())
for idx in range(1, tc+1):
n, m = map(int, input().split()) # 세로 크기 n, 가로 크기 m
arr = list(set([input() for _ in range(n)])) # 중복제거
arr = sorted(arr)[1:] # 0만 있는 배열 제거
numbers = [] # 암호 넣는 리스트
answer = 0
for p in arr:
# 1. 16진수 -> 2진수 변환
# 2. 왼쪽 0 다 제거
# 3. 마지막에 0 붙이기 (마지막 자리를 위해)
binary = format(int(p, 16), 'b').lstrip('0') + '0'
n1 = n2 = n3 = 0 # 각 비율을 담을 변수
cnt = 0 # 암호 8자리 count
odd = 0 # 홀수 자리 합 저장
even = 0 # 짝수 자리 합 저장
temp = ''
for i in range(len(binary)):
if binary[i] == '1' and n2 == 0: # 첫번째 1 비율
n1 += 1
elif binary[i] == '0' and n1 != 0 and n3 == 0: # 두번째 0 비율
n2 += 1
elif binary[i] == '1' and n2 != 0: # 세번째 1 비율
n3 += 1
elif n3 != 0: # 비율 다 구한 경우
cnt += 1
r = min(n1, n2, n3) # 가장 작은 숫자 구하기 (비율 구하기 위함)
pw = ratio[(n1//r, n2//r, n3//r)] # 암호 가져오기
temp += str(pw)
# 마지막 번호인 경우
if cnt == 8:
if (odd * 3 + even + pw) % 10 == 0 and temp not in numbers: # 정상적인 암호코드이고 했던거 아니라면
answer += odd + even + pw # 값 더해주기
numbers.append(temp) # 해당 암호 저장
odd = even = cnt = 0 # 변수들 초기화
temp = ''
# 8번째 자리 이전의 숫자인 경우
elif cnt % 2:
odd += pw # 홀수 자리 더하기
else:
even += pw # 짝수 자리 더하기
n1 = n2 = n3 = 0 # 비율 변수 초기화
print('#{} {}'.format(idx, answer))
포인트 (라고 생각하는 것)
- 딕셔너리 형태로 암호 저장하고 가져오기
- 암호의 비율 중, 맨 앞의 0은 필요없다.
- 왜냐하면 암호코드는 0으로 둘러싸여있고, 암호코드의 앞에도 0이 있기때문에 0부터 고려하면 머리아파진다.
- 그래서 0-1-0-1 비율보다는, 1-0-1 비율로 1부터 count해주면 더 편하다.
- 또한 1-0-1 비율로해도 겹치는 숫자가 없다.
- 중복된 열 제거하기 (set함수 사용)
- 16진수 ➔ 2진수 변환
- 1-0-1 비율 세는 조건문 잘 짜기
- 각 2진수의 비율에 해당하는 각 1과 0(n1, n2, n3)을 다 세었으면, 가장 작은 값으로 각 값을 나눠서 비율 구하기
- 구한 값 중복되지 않도록 암호코드를 이용해 바꾼 숫자를 리스트에 저장하고 체크하기
- 변수들 초기화 해주기
'Algorithm > SW Expert Academy' 카테고리의 다른 글
[Python] 4366. 정식이의 은행업무 (0) | 2021.09.30 |
---|---|
[Python] 10726. 이진수 표현 (0) | 2021.09.30 |
[Python] 5186. 이진수2 (0) | 2021.09.30 |
[Python] 5185. 이진수 (0) | 2021.09.30 |
[Python] 1240. 단순 2진 암호코드 (0) | 2021.09.29 |