알고리즘/자료구조
[백준알고리즘] 스택 - 2304번 창고 다각형 문제
Fenderblue
2023. 5. 8. 02:40
ㅋㅋㅋㅋㅋ네번만에 성공했다^^
스택으로 어찌저찌 풀도록 구현은 했는데 뺴먹은게 너무 많았었다.
경우의 수들을 다 생각 못했었고
마지막에는 >=, >관련해서 제대로 안해놔서 두번이나 틀렸었다
높이가 같은 경우를 다 고려 못했었음
늘 비교 연산자 주의하자..이런걸로 자주 틀리는것같다
예전에 풀어봤던(사실 코드를 짜본건 아니고 풀이법 이해하고 넘어가는정도로 그쳤지만..)
히스토그램 문제도 생각났음..
코드가 몹시 조악하지만 일단 정리안한채로 올려본다
package baekjoonWeek5;
import java.io.*;
import java.util.Arrays;
import java.util.Stack;
import java.util.StringTokenizer;
public class BJ_2304 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
Stack<Integer> stack = new Stack<>();
StringTokenizer st;
int sticks = Integer.parseInt(br.readLine());
int[] stickIdx = new int[sticks]; //막대의 개수만큼 각 막대의 왼쪽면 위치를 차례로 저장할 배열
int[] stickHeight = new int[1001];
for (int i = 0; i < sticks; i++) {
st = new StringTokenizer(br.readLine());
int idx = Integer.parseInt(st.nextToken());
int height = Integer.parseInt(st.nextToken());
stickIdx[i] = idx; //막대수만큼 위치만 따로 저장
stickHeight[idx] = height; //각 막대의 왼쪽면 위치를 나타내는 인덱스자리에 높이를 저장
}
int container = 0;
Arrays.sort(stickIdx); //인덱스가 오름차순으로 안주어져서..정렬해줌
stack.push(stickIdx[0]); //일단 첫번째막대인덱스부터 푸시
for (int i = 1; i < stickIdx.length; i++) {
if (!stack.isEmpty() && stickHeight[stack.peek()] >= stickHeight[stickIdx[i]]) { //스택의 top원소의 높이가 i높이보다 크거나 같다면
stack.push(stickIdx[i]); //스택에 일단 푸시해준다
} else { //스택의 top원소의 높이가 더 작다면 이 시점에서 여기까지의 넓이를 재고 pop한다
while (!stack.isEmpty() && stack.size() > 1 && stickHeight[stack.peek()] <= stickHeight[stickIdx[i]]) { //새로들어오려는 막대보다 작은애들만 pop해준다 여기서 <=말고 <했다가틀릴뻔
stack.pop();
}
if (!stack.isEmpty() && stickHeight[stack.peek()] <= stickHeight[stickIdx[i]]) { //이때 넓이 재줄수있음
container += (stickIdx[i] - stack.peek()) * stickHeight[stack.peek()];
stack.pop(); //넓이 쟀으므로 pop해없앰
stack.push(stickIdx[i]);
} else if (!stack.isEmpty() && stickHeight[stack.peek()] > stickHeight[stickIdx[i]]) {
stack.push(stickIdx[i]); //남아있는 원소보다 i가 더 작으면 i를 푸시만해준다
}
}
}
//마지막막대까지 다 push되었다면 남아있는애들 넓이 따로 구해주기
while (!stack.isEmpty()) { //스택에 원소 남아있다면
if (stack.size() == 1) { //스택에 원소 하나만 남아있었다면
container += stickHeight[stack.pop()];
} else {
int tmp = stack.pop();
container += ((tmp + 1) - (stack.peek() + 1)) * stickHeight[tmp];
}
}
bw.write(Integer.toString(container));
bw.flush();
bw.close();
}
}