Last update: a year ago by nowwaterReading time: 2 min
문제
코드
코드 보기
import java.io.*;import java.util.StringTokenizer;class Main {static int n, m, arr[], seg[];public static void main(String[] args) throws Exception {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StringTokenizer st = new StringTokenizer(br.readLine());n = Integer.parseInt(st.nextToken());m = Integer.parseInt(st.nextToken());arr = new int[n];seg = new int[4 * n + 1];st = new StringTokenizer(br.readLine());for (int i = 0; i < n; i++)arr[i] = Integer.parseInt(st.nextToken());makeSeg(0, n-1, 1);int bought = 987654321;boolean have = false;for (int i = 0; i < n; i++) {if(bought < arr[i]){bought = 987654321;System.out.println(1);}else{int higher = existHigher((i == n - 1 ? n - 1 : i + 1), n - 1, 0, n - 1,1); // segment로 푼다.if(higher > arr[i]){System.out.println(0);bought = arr[i];}else System.out.println(-1);}}}private static int makeSeg(int start, int end, int node) {if (start == end) return seg[node] = arr[start];int mid = (start + end) / 2;return seg[node] = Math.max(makeSeg(start, mid, node * 2), makeSeg(mid + 1, end, node * 2 + 1));}static int existHigher(int left, int right, int start, int end, int node){if(start > right || end < left) return -1;if(left <= start && end <= right) return seg[node];int mid = (start + end) / 2;return Math.max(existHigher(left, right, start, mid, node * 2), existHigher(left, right, mid + 1, end, node * 2 + 1));}}
⭐️느낀점⭐️
세그먼트 트리가 나올줄은 몰랐다. 마지막에 시간이 부족해서 세그먼트 트리를 구현하다가 끝나서 아쉬웠다.. 이번 기회에 다시 복습해서 좋았다.
풀이 📣
1️⃣ 구간 최대값을 저장하는 세그먼트 트리를 만든다.
2️⃣ 현재 값이 이전에 샀던 주식의 가격보다 높다면 바로 판매하고 이전에 샀던 금액을 초기화해준다.
3️⃣ 현재 인덱스 + 1 부터 n-1 까지 구간에서 현재 값보다 큰 값이 존재하는지 쿼리를 날려 확인한다. 더 큰 값이 존재하면 현재 금액으로 주식을 구매하고, 그렇지 않으면 구매하지도 판매하지도 못하므로 -1을 출력한다.
4️⃣ 마지막 인덱스까지 위의 과정을 반복한다.
실수 😅
- 보자마자 세그먼트 트리를 이용해서 풀면 되겠다고 생각했으나, 구현이 완벽하지 않았다.
- 뒤에서 부터 탐색해서 최대값을 저장하는 배열을 만들어서 풀 수도 있을 것 같다.