| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
Tags
- 우선순위큐
- c++
- cpp
- 컴퓨터비전
- level3
- 코틀린
- 백준
- C
- JavaScript
- kotlin
- lv2
- level2
- 임베디드
- Stack
- 자바
- 이분탐색
- BFS
- 2018 KAKAO BLIND RECRUITMENT
- 그리디
- dp
- 동적계획법
- 누적합
- 다이나믹 프로그래밍
- 프로그래머스
- 다이나믹프로그래밍
- 통신 인터페이스
- dfs
- java
- 컴퓨터 비전
- 구현
Archives
- Today
- Total
코드를 느껴바라
22866번 : 탑 보기 [JAVA] 본문
문제 링크=
성공 여부(걸린 시간): 성공(42분 16초)
아이디어
이 문제는 양쪽에서 자신보다 더 큰 건물이 어디에 있는지를 찾아야 하고,
그 건물이 자기 기준으로 얼마나 가까운지, 그리고 그동안 자신이 볼 수 있었던 건물 수는 몇 개인지를 출력해야 하는 문제다.
핵심 아이디어
스택을 이용해 좌측/우측에서 자신보다 큰 건물을 찾는다.
arr[i]보다 큰 건물이 스택의 top에 있을 경우, 해당 건물이 자신이 처음 만나는 큰 건물이 된다.- 그때 스택에 쌓여 있던 건물 수 = 자신이 볼 수 있는 건물 수이므로
cnt[i]에 더해준다.
좌측에서 큰 건물을 찾을 땐 왼쪽부터 오른쪽으로 순회하고, 우측은 오른쪽부터 왼쪽으로 순회한다.
최종 출력 시 조건 분기
- 좌우 모두 큰 건물이 없으면
0출력 - 한쪽에만 큰 건물이 있으면 그쪽 건물 번호 출력
- 양쪽 모두 있으면 더 가까운 건물 번호 출력
- 좌우 모두 큰 건물이 없으면
이 아이디어로 짠 구조
- 스택에
[건물 번호, 높이]형태로 저장 - left[i] = 왼쪽에서 만난 첫 번째 큰 건물 번호
- right[i] = 오른쪽에서 만난 첫 번째 큰 건물 번호
- cnt[i] = 자신이 볼 수 있었던 건물 수 (양쪽 누적)
- 마지막 반복문에서
left[i],right[i],cnt[i]를 기준으로 출력 문자열을 구성함
풀이 코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int [] arr = new int [N+1];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i=1; i<=N; i++){
arr[i] = Integer.parseInt(st.nextToken());
}
ArrayDeque<int []> stack = new ArrayDeque<>();
int [] cnt = new int[N+1];
int [] left = new int [N+2];
// 좌등큰수
stack.add(new int[]{1, arr[1]});
for (int i=2; i<=N; i++){
if(stack.peekLast()[1]>arr[i]){
left[i] = stack.peekLast()[0];
cnt[i]+= stack.size();
} else {
while(!stack.isEmpty()){
if(stack.peekLast()[1]>arr[i]){
left[i] = stack.peekLast()[0];
cnt[i]+= stack.size();
break;
} else {
stack.pollLast();
}
}
}
stack.add(new int[]{i, arr[i]});
}
// 우등큰수
stack.clear();
int [] right = new int [N+1];
stack.add(new int[]{N, arr[N]});
for (int i=N; i>=1; i--){
if(stack.peekLast()[1]>arr[i]){
right[i] = stack.peekLast()[0];
cnt[i]+= stack.size();
} else {
while(!stack.isEmpty()){
if(stack.peekLast()[1]>arr[i]){
right[i] = stack.peekLast()[0];
cnt[i]+= stack.size();
break;
} else {
stack.pollLast();
}
}
}
stack.add(new int[]{i, arr[i]});
}
StringBuilder sb = new StringBuilder();
for(int i=1; i<=N; i++){
if(left[i]+right[i]==0){
sb.append("0");
} else if(left[i]==0||right[i]==0) {
sb.append(cnt[i]+" "+Math.max(left[i], right[i]));
} else {
int nearNum = (Math.abs(left[i]-i) <= Math.abs(right[i]-i)) ? left[i] : right[i];
sb.append(cnt[i]+" "+nearNum);
}
if(i!=N){
sb.append("\n");
}
}
System.out.print(sb);
}
}반응형
'PS > 백준(Baekjoon)' 카테고리의 다른 글
| 16920번 : 확장 게임 [JAVA] (0) | 2025.09.08 |
|---|---|
| 2468번 : 안전 영역 [JAVA] (6) | 2025.08.01 |
| 2234번 : 성곽 [JAVA] (0) | 2025.07.24 |
| 14890번 : 경사로 [JAVA] (0) | 2025.04.07 |
| 17143번 : 낚시왕 [JAVA] (4) | 2025.04.06 |
