본문 바로가기

Algorithm

백준 3015 오아시스 재결합 Java

알고리즘 분류에 스택으로 분류되어 있는 오아시스 재결합 문제이다.

 

문제를 간단히 설명하면

사람 수 N이 주어지고 N명의 사람들의 키가 순서대로 주어진다.

이 순서대로 줄을 서있을 때 A와 B가 마주 볼 수 있는 경우의 수를 출력하면 된다.

A와 B 사이에 A 또는 B보다 큰 사람이 있으면 안 된다.

 

N이 500,000이기 때문에 O(N^2)으로 비교해가면서 풀 수 없는 문제이다.

스택을 활용해야 한다는 힌트를 알았기 때문에

주어진 키를 전부 스택에 넣고 어떻게 활용하면 O(N)만에 풀 수 있을까

고민했는데 답이 안 나왔다.

 

답이 안 나온 이유는 주어진 키를 전부 스택에 넣었기 때문이다.

이 문제는 키를 하나씩 스택에 넣어가며 풀어야 된다.

for문을 돌면서 i번째 사람보다 i+1번째 사람이 키가 큰 경우 

i+1부터 그다음 사람들은 모두 i번째 사람과 마주 볼 수 없다는 점을 이용하면

O(N)만에 풀 수 있다.

 

푸는 방법을 설명하는 글을 몇 번이나 썼다 지웠다 했지만

이 문제는 코드가 간단하기 때문에 코드를 보면서 이해하는 게 빠를 것 같다.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 
public class Q3015 {
 
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(reader.readLine());
        Stack<Pair> s = new Stack<>();
        long ans = 0;
 
        for(int i=0; i<n; i++) {
            int k = Integer.parseInt(reader.readLine());
            Pair p = new Pair(k, 1);
            while(!s.isEmpty()) {
                if(s.peek().x <= p.x) {
                    ans+= s.peek().y;
                    if(s.peek().x == p.x){
                        p.y += s.peek().y;
                    }
                    s.pop();
                } else {
                    break;
                }
            }
            if(!s.isEmpty()) {
                ans += 1;
            }
            s.push(p);
        }
        System.out.println(ans);
    }
}
class Pair{
    int x; //키
    int y; //키가 같은 사람
 
    public Pair(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
 

주어질 수 있는 키의 범위가 2^31 미만이고 N이 오십만 이하 이기 때문에

마주 볼 수 있는 경우의 수가 int의 범위를 넘을 수 있다.

때문에 정답을 저장할 변수는 꼭 long으로 자료형을 지정해야 한다.

'Algorithm' 카테고리의 다른 글

백준 1717 집합의 표현 Java  (0) 2019.08.07
유니온 파인드  (0) 2019.08.07
백준 14889 스타트와 링크 Java  (0) 2019.08.05
백준 2231 분해합 Java  (6) 2019.07.29
백준 1712 손익분기점 Java  (0) 2019.07.26