문제 홈페이지 : programmers.co.kr/learn/courses/30/lessons/42862
코딩테스트 연습 - 체육복
점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번
programmers.co.kr
문제 설명
점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.
제한사항
- 전체 학생의 수는 2명 이상 30명 이하입니다.
- 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
- 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
- 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
- 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.
나의 풀이
def solution(n, lost, reserve):
reserve.sort()
lost.sort()
for j in lost:
for i in reserve:
if i == j:
lost[lost.index(j)] = -2
reserve[reserve.index(i)] = -2
break
reserve = list(set(reserve))
if -2 in reserve:
reserve.remove(-2)
lost = list(set(lost))
if -2 in lost:
lost.remove(-2)
for j in lost:
for i in reserve:
if (j - 1 == i) | (j + 1 == i):
lost[lost.index(j)] = -2
reserve[reserve.index(i)] = -2
break
reserve = list(set(reserve))
if -2 in reserve:
reserve.remove(-2)
lost = list(set(lost))
if -2 in lost:
lost.remove(-2)
return n-len(lost)
이 문제를 푸는동안 한가지 문제가 발생해서 꽤나 골머리를 썩었다. for (parameter) in (list): 와 같은 방식으로 반복문을 사용할 때는 for문 내부에서 (list)를 수정하면 문제가 생긴다는 것이다. for문 안에서 (list)값중 하나를 삭제하게 되면, 순서가 꼬여서 (list)안의 모든 값을 (parameter)로 가져오지 않는다. 이는 for문에서 list를 index기준으로 참조하기 때문인 것으로 보인다. 이를 해결하기 위해서, 특정값을 삭제하지 않고, 다른 값으로 대체한 후에 반복문이 끝나고 나서 제거해주는 형태로 문제를 해결했는데 언듯보기에도 지저분하고 파이썬스럽지 않다. 여기서 몇가지 공부해야 할 사항들을 확인할 수 있다.
추가적으로 공부해야할 사항
- 적어도 파이썬 문법정도는 확실하게 알자.
아직 파이썬을 제대로 공부해본적 없는 것도 맞지만, 그래도 이런저런 핑계로 대충 넘어가면 실력은 언제느냐 - 반복문이 내부적으로 어떻게 돌아가고 있는지 (in이라는 키워드에 대한 이야기도 포함이다.) 확인하자.
- set자료형에 대해서 자세히 알아보자
Best답안
def solution(n, lost, reserve):
_reserve = [r for r in reserve if r not in lost]
_lost = [l for l in lost if l not in reserve]
for r in _reserve:
f = r - 1
b = r + 1
if f in _lost:
_lost.remove(f)
elif b in _lost:
_lost.remove(b)
return n - len(_lost)
추가적으로 공부해야할 사항
- _reserve = [r for r in reserve if r not in lost]와 같은 방법으로 list를 정의하는 것에대해서 자세히 확인해볼 필요가 있다.
- 변수를 추가적으로 할당하는 것에 대해서 무서워하지 말자. 메모리 조금더 소비해도 코드 깔끔한 편이 훨신 낫다.
'Algorithm' 카테고리의 다른 글
백준 1026번: 보물(python) (0) | 2022.02.08 |
---|---|
프로그래머스 > 코딩테스트 연습 > 해시 > 완주하지못한 선수 (0) | 2021.02.08 |