문제 링크 : https://www.acmicpc.net/problem/12787
1. 접근 방법
기본적으로 2진수 <-> 10진수 변환과 문자열을 수정해 특정 길이로 맞춰주는 과정이 필요하다
문제는 간단하게 해결됐지만, 해결 방법을 공유하면 좋을 것 같아서 작성한다
2. 해결 코드
- 파이썬 해결 코드
import sys
input = sys.stdin.readline
for _ in range(int(input())):
m, n = input().strip().split()
if m == '1':
ans = ''
ip = list(map(int, n.split('.')))
for p in ip:
ans += bin(p)[2:].zfill(8)
print(int(ans, 2))
else:
ans = ''
ip = str(bin(int(n))[2:]).zfill(64)
for i in range(8):
ans += str(int(ip[i * 8:(i + 1) * 8], 2))
if i != 7:
ans += '.'
print(ans)
- 풀이 과정
기초 지식 1. int
https://docs.python.org/ko/3/library/functions.html#int
int는 내장 함수이고, 특별히 입력하는 수의 '진수(base)'를 입력할 수 있다. 기본값은 base = 10이며, base값에 따라 자동적으로 해당 진수에서 10진수로 변환해준다. 추가적으로 9의 2진수 1001을 입력으로 할 때, '1001'과 bin함수를 통하여 얻은 '0b1001'모두 입력으로 가능하다. 하지만 '0b1001'과 같이 알파벳을 포함함 입력일 때, 해당 진수를 알려주지 않으면 ValueError가 발생한다.
int('1001') # 1001
int('1001', 2) # 9
int('0b1001', 2) # 9
int('0b1001') # ValueError
기초 지식 2. zfill
https://docs.python.org/ko/3/library/stdtypes.html?highlight=zfill#str.zfill
zfill은 문자열 메서드이고, 원하는 길이를 입력하면 해당 길이가 될 때 까지, 나머지 길이를 원래 문자열 왼쪽에 0을 채워 넣는다. 원래 문자열 길이보다 더 짧게 입력하여도 기존 문자열에 문제가 생기지 않으므로, 특정 길이를 맞춰줘야 하는 문제에서 사용하면 좋은 메서드다.
'1001'.zfill(8) # 000010001
'1001'.zfill(4) # 1001
'1001'.zfill(3) # 1001
변환 방법 1과 2일 때를 우선 구분하여 시행한다.
변환 방법 1일때는 우선 콤마를 기준으로 수를 구분한 뒤, 2진수로 표현한다. 이때, 길이가 달라질 수 있기에 zfill을 활용, 모두 8자리로 맞춘 뒤 int함수를 사용 2진수에서 10진수로 변환하여 출력한다
변환 방법 2일때는 수를 2진수로 바꾼 후 8자리로 구분해야 하는데, 총 64자리가 안될 수도 있다. 따라서 zfill을 활용 64자리로 만들고, 왼쪽에서부터 8자리씩 확인하여 10진수로 표현, 각 수를 콤마로 있어 붙여서 출력한다.
3. 생각 정리
파이썬은 PS세 사용하기 좋은 함수들이 많다. 하지만 그만큼 함수들을 잘 사용하고, 원리를 잘 아는 것이 더 중요하다고 생각한다. 이런 환경은 양날의 검과 같아서, 더욱 빠르게 많은 문제를 효율적으로 해결할 수도 있지만, 미처 잘 인지하지 못한 내용에 대한 공부를 더디게 할 수 있다.
int함수의 base활용은 진수 변환의 시간과 코드 양을 줄일 수 있는 방법이다. 하지만 진수 변환의 원리를 알지 못하거나, 헷갈린다면 바로 사용하는 것은 오히려 나쁠 수도 있다고 생각하다.
zfill메서드는 매우 간단하고 효율적인 함수이기는 하지만, 그 사용용도가 매우 한정적이다. 물론 이번 문제와 비슷한 경우면 활용하는 것이 좋다고 생각하지만, 대안으로 활용할 다양한 방법을 잘 아는 것도 중요하다. 대안으로 활용한 방법은 크게 2가지 정도를 생각할 수 있다.
첫 번째는 0으로 모두 채워야 할 공간의 수 n에 대하여 10 ** (n + 1)을 더하여 슬라이싱 하는 방법이다. 이 방법은 매우 간단하지만, 0으로 채우는 것 이외의 방법에서는 제한적이다
a = '1001'
a = str(int(a) + 10 ** 8)
a = a[-8:]
# 00001001
두 번째는 문자열 기준으로 왼쪽에 0을 채워줄 수 있다. 최적화를 한다면, 채워야 할 길이를 구해서 붙여도 되지만, 0으로만 이루어진 길이 n문자열과 기존 문자열을 붙여서 만든 후 슬라이싱을 하는 방법도 가능하다.
a = '1001'
a = '0' * 8 + a
a = a[-8:]
# 00001001
- zfill을 활용해서 풀 수 있는 문제
백준 6568 귀도 반 로썸은 크리스마스날 심심하다고 파이썬을 만들었다 (https://www.acmicpc.net/problem/6568)
- 출력에서만 사용됨
풀이 글 : [Python] 백준 6568 귀도 반 로썸은 크리스마스날 심심하다고 파이썬을 만들었다
'CS > 알고리즘 & 문제풀이' 카테고리의 다른 글
[Python] 백준 9080 PC방 요금 (0) | 2021.10.07 |
---|---|
[Python] 백준 2572 보드게임 (0) | 2021.09.21 |
[Python] 백준 6568 귀도 반 로썸은 크리스마스날 심심하다고 파이썬을 만들었다 (0) | 2021.09.19 |
[Python] 백준 1338 알 수 없는 번호 (0) | 2021.09.18 |
[Python] 백준 5052 전화번호 목록 (0) | 2021.09.15 |
댓글