[BOJ] 20546번 기적의 매매법 - JAVA

최영환·2024년 8월 13일
0
post-thumbnail

💡 문제

💬 입출력 예시

📌 풀이(소스코드)

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    static final int SIZE = 14;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int money = Integer.parseInt(br.readLine());
        int[] costs = new int[SIZE];

        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i < SIZE; i++) {
            costs[i] = Integer.parseInt(st.nextToken());
        }

        // 두 방법의 최종 결과 값만 알면됨
        int bnpRet = bnp(costs, money);
        int timingRet = timing(costs, money);

        if (bnpRet > timingRet) {
            System.out.println("BNP");
        } else if (bnpRet < timingRet) {
            System.out.println("TIMING");
        } else {
            System.out.println("SAMESAME");
        }
    }

    private static int bnp(int[] costs, int money) {
        int stocks = 0;
        for (int cost : costs) {
            if (cost <= money) {
                stocks += money / cost;
                money -= cost * (money / cost);
            }
        }
        return costs[costs.length - 1] * stocks + money;
    }

    private static int timing(int[] costs, int money) {
        int stocks = 0;
        int upCnt = 0;
        int downCnt = 0;

        for (int i = 0; i < costs.length; i++) {
            // 하락
            if (i != 0 && costs[i] < costs[i - 1]) {
                downCnt++;
            } else {
                downCnt = 0;
            }
            if (i != 0 && costs[i] > costs[i - 1]) {
                upCnt++;
            } else {
                upCnt = 0;
            }

            if (upCnt >= 3) {
                money += costs[i] * stocks;
                stocks = 0;
            }

            if (costs[i] <= money && downCnt >= 3) {
                stocks += money / costs[i];
                money -= costs[i] * (money / costs[i]);
            }
        }
        return stocks * costs[costs.length - 1] + money;
    }
}

📄 해설

접근

  • 구현 문제는 사실 크게 접근이랄게 없다. 최근 풀이한 문제들이 전부 실버 난이도 이하여서, 너무 오랫동안 글을 작성하지 않는 것에 불안감을 느끼고 작성한다.
  • 두 경우를 메소드로 나눠서 구현을 했다.
  • BNP 는 단순히 매수 가능할 때 전량 매수를 하고, 마지막 날의 값과 계산을 한다.
  • TIMINGBNP 보다는 복잡하다. 하락이나 상승이 3일 연속 이루어지고 있는지를 계속해서 확인하고, 3일 째 하락이나 상승이 이루어졌을 때, 매수나 매도 로직을 수행하면 된다.

과정

  • 시작 자금을 입력 받고, 14일 동안의 주식 가격을 입력 받아 costs 배열에 저장한다.
  • BNP 의 결과값을 얻는 메소드와 TIMING 의 결과값을 얻는 메소드를 각각 실행하고, 둘의 결과 값을 비교하여 둘 중 큰 값을 가진 방법을 출력한다. 같으면 SAMESAME 을 출력한다.
  • BNP 메소드의 흐름은 다음과 같다.
    • 현재 갖고 있는 현금이 주식의 가격과 크거나 같다면 바로 전량 매수를 한다.
  • TIMING 메소드의 흐름은 다음과 같다.
    • 오늘 주식의 가격이 전날보다 상승했는지, 하락했는지를 확인하기 위해 upCnt 변수와 downCnt 변수를 유지한다.
    • upCnt 변수가 3 이상이 될 경우, 전량 매도를 수행한다.
    • downCnt 변수가 3 이상이고 매수할 수 있다면 전량 매수를 수행한다.
  • 두 메소드 모두 결과 값을 얻는 방법은 다음과 같이 동일하다.
    • 반복 종료 후, 현재 주식의 개수 * 마지막날 주식의 가격 + 보유 현금 을 반환한다.
  • 출력부에 대한 설명은 생략하겠다.
profile
조금 느릴게요~

0개의 댓글