반응형

2563번 문제는 2차원 배열 문제입니다.

 

단순히 배열을 처리하는 문제라 풀이 과정 자체는 안 어려운데요.

import sys

paper = [[0]*100]*100
input = sys.stdin.readline

for _ in range(int(input().rstrip())):
    a, b = map(int, input().split())
    for _ in range(a, a+10):
        for __ in range(90-b, 100-b):
            paper[_][__] = 1
area = 0
for _ in range(100):
    for __ in range(100):
        if paper[_][__] == 1:
            area += 1
print(area)

 

예제 입력 1을 넣어봤는데, 계속 지나치게 큰 output이 나오더라고요.

그래서 코드를 다시 쭉 복기했더니 paper = [[0]*100]*100 부분을 shallow copy로 생성했더라고요.

 

즉, [[0]*100]*100이 모두 [[0]*100]을 참조하게 되어 해당 리스트의 값이 하나라도 밖이면 전부 같이 바뀌게 됩니다.

 

예를 들어,

paper = [[0]*5]*5
paper[0][0] = 1
print(paper)

를 쓰게 되면

[[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]로 모든 행의 첫 번째 열이 1로 변하게 됩니다.

 

따라서, 이를 방지하기 위해선 처음 리스트를 생성할 때 리스트 컴프리헨션을 사용해야 합니다.

paper = []

for _ in range(100):
    paper.append([0]*100)
    
#########################################
paper = [[0]*100 for _ in range(100)]

이러면 각 내부 리스트가 독립적인 객체로 생성되기 때문에 얕은 복사 문제를 피할 수 있습니다.

여기에 맞게 코드를 수정하면 다음과 같습니다.

import sys

paper = [[0]*100 for _ in range(100)]
input = sys.stdin.readline

for _ in range(int(input().rstrip())):
    a, b = map(int, input().split())
    for _ in range(a, a+10):
        for __ in range(90-b, 100-b):
            paper[_][__] = 1
area = 0
for _ in range(100):
    for __ in range(100):
        if paper[_][__] == 1:
            area += 1
print(area)

결과는

입니다.

 

 

 

 

 

 

 

 

 

 

오늘의 교훈

리스트를 복사하거나 생성할 땐 shallow copy와 deep copy를 잘 구분하자.

 

 

 

 

 

 

 

 

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------

+a

 컴프리헨션(comprehension)이라고 인터넷에 검색하면 이해력이라는 뜻이 나오는데요. 리스트 컴프리헨션(list comprehension)을 단순히 리스트 이해력이라는 생각 하면 좀 이상합니다. 또 리스트 표현식이라는 표현도 쓰긴 하는데 expression이랑은 단어가 달라서 의미가 미묘하게 다른 것 같습니다. 그래서 어원사전에서 comprehension을 찾아봤는데요.

 내용을 정리해 보면 통합하다는 뜻이 가장 가까워 보이고요. 여기에 맞게 해석하면 여러 줄로 정의되는 반복문을 한 줄로 통합한다라는 뜻인 것 같습니다. 리스트 반복통합식(?)이라고 해야 되나, 정확히 한글식 표현으론 뭘 써야 될지는 모르겠네요. 혹시 괜찮은 표현 있으면 댓글 부탁드립니다.

 

 

참고 사이트

comprehension 어원 사전 사이트

 

comprehension | Search Online Etymology Dictionary

The online etymology dictionary (etymonline) is the internet's go-to source for quick and reliable accounts of the origin and history of English words, phrases, and idioms. It is professional enough to satisfy academic standards, but accessible enough to b

www.etymonline.com

python list comprehension 설명 사이트

 

1) 리스트 컴프리헨션

## 리스트 생성하기 기존에 배운 문법으로 1부터 10까지 정수를 순서대로 가지고 있는 리스트를 생성하는코드는 다음과 같습니다. ``` numbers = [] for n i…

wikidocs.net

 

반응형

'백준 > 오답노트' 카테고리의 다른 글

[백준 오답노트] 1152번 split(' ')과 split()의 차이  (0) 2024.11.05
반응형

문제 1152

 

 오늘의 오답 노트는 1152번입니다.

 간단하게 문장 내의 단어의 개수를 출력하는 문제로 굉장히 쉬워보이는 문제인데요.

 하지만 정답 비율은 무려 33.223%. 무언가 함정이 있다는 것을 알아버렸습니다.

 자세히 마저 읽다보니, 예제 입력에 처음공백이 추가적으로 들어갈 수 있다는 것을 알아버렸습니다. 예제 입력 2를 보면 다른 출력과 다르게 앞에 공백이 있습니다. 예제 입력 3은 맨 뒤에 공백이 있구요.

 

 따라서 저는 sys.stdin.readline().strip()을 통해 양 끝의 공백과 엔터를 지워주고, split(' ')을 통해 공백으로 단어를 구분해주기로 했습니다.

import sys

input = lambda:sys.stdin.readline().strip()
print(len(input().split(' ')))

 하지만 결과는 틀렸습니다....

그래서 split() 공식문서를 좀 더 찾아보니

라고 하더군요.

 

즉 split()과 split(' ')는 다르다는 겁니다.

 split()같은 경우는 공백이 연속적으로 있는 것과 상관 없이 안에 있는 값만을 리스트의 요소로 넣어서 반환하고요.

 split(' ')의 경우는 중간에 값이 없으면 ''(공백) 자체가 리스트의 요소로 넣어져서 반환됩니다.

 

따라서, 제가 만든 코드는 공백만 입력으로 들어오면 0을 반환해야되는데 1을 반환해서 틀렸다는 것을 알아버렸습니다.

 

이제 문제를 파악했으니 해결해봅시다.

split()을 쓰면 " 공백이 연속적으로 있는 것과 상관 없이 안에 있는 값만을 리스트의 요소로 넣어서 반환한다."는 특성을 활용해 기존의 strip()과 split(' ') 대신에 split()만을 사용해 간단하게 코드를 작성할 수 있습니다.

import sys

print(len(sys.stdin.readline().split()))

sys.stdin.readline()을 통해 입력을 읽어주고요.

.split()을 통해 문자열을 단어 단위로 나눠서 list로 반환해줍니다.

마지막으로 len을 통해 해당 리스트의 개수를 반환합니다.

 

 

 

결과는,

성공!

 

 

오늘의 교훈

공식 문서를 정독하자.

 

 

참고 자료

https://docs.python.org/ko/3/library/stdtypes.html#str.split

 

반응형

+ Recent posts