[백준] 주식(11501) - python

당고짱·2022년 5월 28일
0

coding-test

목록 보기
23/50
post-thumbnail

✏️ 문제

홍준이는 요즘 주식에 빠져있다. 그는 미래를 내다보는 눈이 뛰어나, 날 별로 주가를 예상하고 언제나 그게 맞아떨어진다. 매일 그는 아래 세 가지 중 한 행동을 한다.

  1. 주식 하나를 산다.
  2. 원하는 만큼 가지고 있는 주식을 판다.
  3. 아무것도 안한다.

홍준이는 미래를 예상하는 뛰어난 안목을 가졌지만, 어떻게 해야 자신이 최대 이익을 얻을 수 있는지 모른다. 따라서 당신에게 날 별로 주식의 가격을 알려주었을 때, 최대 이익이 얼마나 되는지 계산을 해달라고 부탁했다.

예를 들어 날 수가 3일이고 날 별로 주가가 10, 7, 6일 때, 주가가 계속 감소하므로 최대 이익은 0이 된다. 그러나 만약 날 별로 주가가 3, 5, 9일 때는 처음 두 날에 주식을 하나씩 사고, 마지막날 다 팔아 버리면 이익이 10이 된다.

🎈 입력

입력의 첫 줄에는 테스트케이스 수를 나타내는 자연수 T가 주어진다. 각 테스트케이스 별로 첫 줄에는 날의 수를 나타내는 자연수 N(2 ≤ N ≤ 1,000,000)이 주어지고, 둘째 줄에는 날 별 주가를 나타내는 N개의 자연수들이 공백으로 구분되어 순서대로 주어진다. 날 별 주가는 10,000이하다.

🎈 출력

각 테스트케이스 별로 최대 이익을 나타내는 정수 하나를 출력한다. 답은 부호있는 64bit 정수형으로 표현 가능하다.

🎈 입출력 예

<입력>
3
3
10 7 6
3
3 5 9
5
1 1 3 1 2

<출력>
0
10
5

👩‍💻 내 코드

이 문제는 그리디 알고리즘을 이용해 푸는 문제이다. 직접 구현한 코드로는 시간 초과로 문제를 해결하지 못해 다른 사람들이 구현한 코드를 보고 비교해보았다. 내가 생각한 아이디어는 아래와 같다.

  1. 가장 큰 주가와 작은 주가를 구한다.
  2. 뽑아낸 원소가 가장 작은 주가와 같다면 benefit 배열에 넣는다.
  3. 뽑아낸 원소가 가장 큰 주가와 같다면 benefit 배열에 있는 원소들을 판 값을 구한다.
from collections import deque

T = int(input())

for _ in range(T):
    N = int(input())
    stock = deque(list(map(int, input().split())))

    benefit = []
    stock_min = min(stock)
    stock_max = max(stock)
    total = 0

    while len(stock) > 0:
        tmp = stock.popleft()
        if tmp == stock_min and len(stock) > 0:
            benefit.append(tmp)
        elif tmp == stock_max and len(benefit) > 0:
            while len(benefit) > 0:
                total += (tmp-benefit.pop())
        if len(stock) > 0:
            stock_min = min(stock)
            stock_max = max(stock)
    print(total)

내가 구현한 코드의 문제는 높은 주가를 계속 갱신하는 곳에서 문제가 생기는 것 같았다. 그래서 이 곳의 코드를 참고해 다시 구현했다. 내 코드와의 다른 점은 원소를 뒤에서부터 비교하는 것 이었다. 뒤에서부터 비교하면 싼 가격이면 바로 팔고 비싸면 그것을 기준으로 다시 반복하면 되기 때문이다.

T = int(input())

for _ in range(T):
    N = int(input())
    stock = list(map(int, input().split()))

    total = 0
    
    while len(stock) > 0:

        tmp = stock.pop()

        for i in range(len(stock)-1, -1, -1):
            if tmp >= stock[i]:
                total += (tmp-stock[i])
                stock.pop()
            else:
                break
    
    print(total)

앞에서부터 원소를 꺼내서 비교하는 것이 훨씬 복잡하고 구현하기 어렵다는 것을 알았다. 나와 다르게 구현한 코드를 보고 비교하니 내가 부족한 점이 무엇인지 잘 알 수 있었다.ㅎㅎ

profile
초심 잃지 말기 🙂

0개의 댓글