링크 : https://www.acmicpc.net/problem/2064
문제 설명
네트워크에 연결되어 있는 컴퓨터들은 각각 하나의 IP 주소를 갖게 된다. 그리고 이러한 IP 주소를 갖는 컴퓨터들이 여러 개 모여서 하나의 IP 네트워크를 구성하게 된다. IP 네트워크는 ‘네트워크 주소’와 ‘네트워크 마스크’라는 두 개의 정보로 표현된다.
IP 주소는 네 개의 바이트로 구성되어 있으며, 각각을 10진수로 나타내고(앞에 0을 붙이지 않은 형태로) 사이에 점을 찍어 주소를 표현한다. 바이트이기 때문에 각각의 수는 0부터 255까지의 값을 갖게 된다. 네트워크 주소와 네트워크 마스크 역시 같은 형식으로 나타낸다.
IP 네트워크에 대해 올바르게 이해하기 위해서는 위와 같은 주소를 2진수로 이해하면 된다. 즉, 각각의 바이트를 8자리의 이진수로 나타내고, 이를 네 개 붙여놓은(앞에서부터) 32자리의 이진수를 생각해 보자. IP 네트워크에는 기본적으로 2m 개의 컴퓨터(혹은 IP 주소)가 할당될 수 있다. 이 경우의 네트워크 주소는 앞의 32-m 자리가 임의의 수(0 또는 1)로 구성되어 있고, 뒤의 m자리는 0으로 채워지게 된다. 네트워크 마스크는 앞의 32-m 자리가 1로 채워져 있고, 뒤의 m자리는 0으로 채워지게 된다. 이와 같은 IP 네트워크에는 앞의 32-m 자리가 네트워크 주소와 일치하는 모든 IP들이 포함되게 된다.
예를 들어 네트워크 주소가 194.85.160.176이고, 네트워크 마스크가 255.255.255.248인 경우를 생각해 보자. 이 경우, 이 네트워크에는 194.85.160.176부터 194.85.160.183까지의 8개의 IP 주소가 포함된다.
어떤 네트워크에 속해있는 IP 주소들이 주어졌을 때, 네트워크 주소와 네트워크 마스크를 구해내는 프로그램을 작성하시오. 답이 여러 개인 경우에는 가장 크기가 작은(포함되는 IP 주소가 가장 적은, 즉 m이 최소인) 네트워크를 구하도록 한다.
제한조건
첫째 줄에 정수 n(1 ≤ n ≤ 1,000)이 주어진다. 다음 n개의 줄에는 각 컴퓨터의 IP 주소가 주어진다.
코드
import sys
input = sys.stdin.readline
def printIP(ip):
a = int(ip[:8], 2)
b = int(ip[8:16], 2)
c = int(ip[16:24], 2)
d = int(ip[24:32], 2)
print(format(a) + '.' + format(b) + '.' + format(c) + '.' + format(d))
N = int(input())
address = []
for _ in range(N):
a, b, c, d = map(int, input().split('.'))
address.append(format(a,'08b')+format(b,'08b')+format(c,'08b')+format(d,'08b'))
m = 0
for ip in address:
for i in range(32):
if address[0][i] != ip[i]:
m = max(m, 32-i)
network = address[0][:-m] + '0'*m if m!= 0 else address[0][:]
mask = '1'*(32-m) + '0'*m
printIP(network)
printIP(mask)
아이디어
1. 처음에는 비트연산으로 할려고 계속 했지만 네트워크 주소는 구하기 쉬워도 네트워크 마스크를 어떻게 구별해야 할지 계속 문제였다...
2. 짧은 지식으로 조금 더 생각해본 결과 서브넷 마스크를 쓰는 이유도 결국 내 ip로 네트워크 접속을 &연산자 하나로 간편하게 하는거지 그 역이 편할거라는 보장은 없는거 아닌가? 라는 생각이 들게 되었다...
3. 그래서 그냥 문자열로 싹다 이은 후, 가장 큰 차이가 나는 m 구간을 구해서 m으로 네트워크와 마스크를 구하는 방식을 사용했다.
4. 80%에서 value error가 나와 질문게시판을 확인하니 0.0.0.0이 입력으로 들어왔을 때 처리가 안되어 있었던 이유였다...
network = address[0][:-m] + '0'*m 부분에 만약에 m이 0이면 그냥 기존 입력을 그대로 쓰는부분을 추가했다.
5. format에서 format(a, 'b')로 바이너리로 변환만 했었는데 에러가 계속나서 알고보니 파이썬은 '08b'처럼 간격 지정을 안해주면 그냥 앞에가 0이면 줄여서 반환해주는 것 같다. 나중에 자주 쓸만한거는 정리가 필요!
'알고리즘' 카테고리의 다른 글
BOJ -22862 가장 긴 짝수 연속한 부분수열 (large) (0) | 2023.02.02 |
---|---|
프로그래머스 - 입국심사(43238) (0) | 2023.01.29 |
프로그래머스 - 정수 삼각형 (0) | 2023.01.26 |
백준 - 부분합 (0) | 2023.01.09 |
백준 - RGB거리 (0) | 2022.12.20 |