백준 2309번 : 일곱 난쟁이

상은·2022년 2월 16일
0

백준문제

목록 보기
2/12

백준 2309번 문제

풀이

arr = [int(input()) for _ in range(9)]      # 9명의 키 입력받기
total = sum(arr)                            # 9명의 키의 합

# 키 순으로 정렬
arr.sort()

# 투포인터로 접근
s = 0
e = 8 # 9 - 1

while s < e :
    # 2명의 합이 30 이라면
    # 남은 7명의 합이 100 이니까
    if arr[s] + arr[e] == total - 100 :
        for i in range(9):
            if i == s or i == e :
                continue
            print(arr[i])
        break
    # 2명의 합이 30보다 크다면 후진
    elif arr[s] + arr[e] > total - 100:
        e -= 1
    # 2명의 합이 30보다 작으면  전진
    else :
        s += 1

아홉 명의 키를 arr 리스트에 저장한다.
7명의 난쟁이의 키의 합이 100이 조건이다.

7명을 일일히 다 구해서 합이 100인 경우를 찾는 것보다 총합에서 2명의 키를 뺐을 때 100인 경우를 찾는 것이 2명만 찾으면 되기 때문에 문제를 더 쉽게 이해할 수 있다.

먼저 arr의 전체 합을 total에 저장시켰고, 투포인터로 접근하기 위해 arr리스트를 정렬시켜주었다.

s는 시작점을 e는 끝점을 의미한다.

시작점이 끝점과 같아지거나 추월하기 전까지 계속해서 while문을 통해 7명의 난쟁이를 구해보자.

arr의 총합이 130 이기때문에 2명의 키의 합이 30인 경우를 찾으면 된다.

if문을 통해 2명의 키의 합이 30이면 for문을 통해 7명의 난쟁이들의 키를 각각 출력하게 하면 된다. for문 안에 if문에 시작점과 끝점이 인덱스의 순서와 같게되는 경우는 continue를 통해 출력이 안 나오게한다.

elif문을 통해 2명의 키의 합이 30보다 작다면, 끝점을 한칸 땡겨서 옮긴다. 그리고 나서 다시 while문을 반복한다.

else문을 통해 2명의 키의 합이 30보다 크다면, 시작점을 한칸 앞으로 옮긴다. 그리고 나서 다시 while문을 반복한다.

시작점과 끝점을 한칸씩 옮길 수 있는 이유는 위에서 arr을 오름차순으로 정렬했기 때문에 가능하다.

문제의 예제값을 보면 20 7 23 19 10 15 25 8 13 이다.
이를 정렬하면 7 8 10 13 15 19 20 23 25 이 되는데,
s는 0 , e는 8로 주어졌으므로
arr[s]은 7 , arr[e]은 25가 되게 된다.

일단 arr[s] 와 arr[e] 의 합은 32 이다. 이때 시작점을 앞으로 한칸 옮기면 32보다 더 크게 된다. 따라서 끝점을 한칸 땡겨서 옮긴다. 위의 정렬된 arr의 경우에는 같은 수가 없어서 무조건 32보다 작아진다. 같은 수가 있는 경우는 같거나 작아지는 경우가 나오는데, 종합적으로는 32보다 더 커지진 않기때문에 이런 인덱스의 변화를 줄 수 있는 것이다.

이상으로 투포인터를 활용한 문제풀이였다.

profile
Be the Best

0개의 댓글