www.acmicpc.net/problem/17298

 

17298번: 오큰수

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.

www.acmicpc.net

스택으로 구현할 수 있고, 시간초과에 주위해야하는 문제입니다.

자바에서는 출력만으로도 시간초과가 나올 수 있기때문에 반복적인 System.out.println 보다는

StringBuffer, StringBuilder, BufferedWriter 중에서 사용해야합니다.

 

우선 오큰수는 자신의 오른쪽에 있는 숫자들 중에서 자신보다 큰 수 중에 가장 왼쪽에 있는 수를 말합니다.

 

저는 이 문제를 해결하기 위해 수열의 역순으로 탐색을 하였습니다.

list[i]를 스택에 넣기 전에 자신보다 작은 값들을 전부 pop해준 후에 남아있는 스택의 top에 있는 값이 오큰수 입니다.

 

먼저 스택이 비어있다면 자신이 가장 큰 수이므로 -1입니다.

비어있지 않다면 스택의 top이 오큰수입니다.

 

이 값들을 StringBuffer에 다 append를 해준 후에 마지막에 sb.toString()을 출력해주시면 되겠습니다.

 

 

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
46
47
48
49
50
51
52
53
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static Stack<Integer> s = new Stack<>();
    static int list[], ans[];
    static int N;
 
    static void print() {
        for (int i = 0; i < N; i++) {
            sb.append(ans[i] + " ");
        }
 
        System.out.println(sb.toString() + "\n");
    }
 
    static void func() {
        for (int i = N - 1; i >= 0; i--) {
            while (!s.isEmpty() && s.peek() <= list[i])
                s.pop();
 
            if (s.isEmpty())
                ans[i] = -1;
            else
                ans[i] = s.peek();
 
            s.add(list[i]);
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N];
        ans = new int[N];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 6198 옥상 정원 꾸미기  (0) 2021.01.26
boj 1874 수택 수열  (0) 2021.01.25
boj 4358 생태학  (0) 2021.01.25
boj 5639 이진 검색 트리  (0) 2021.01.24
boj 1991 트리 순회  (0) 2021.01.22

www.acmicpc.net/problem/4358

 

4358번: 생태학

프로그램은 여러 줄로 이루어져 있으며, 한 줄에 하나의 나무 종 이름이 주어진다. 어떤 종 이름도 30글자를 넘지 않으며, 입력에는 최대 10,000개의 종이 주어지고 최대 1,000,000그루의 나무가 주어

www.acmicpc.net

나무의 각 종의 이름이 입력으로 들어오면 사전순으로 각 종의 비율을 출력하는 문제입니다.

사전순으로 출력하기 위해 Map 중에서 TreeMap을 사용하였습니다.

 

이름이 주어질 때마다 새로운 이름이면 생성하여 맵에넣고, 기존에 있던 이름이면 +1.0한 값을 맵에 넣어줍니다.

 

맵의 데이터들을 출력하기 위해 Entry를 사용하였고, e.getKey()(이름)과 e.getValue()/N *100 (비율)을 출력하였습니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Map.Entry;
import java.util.TreeMap;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static String st;
    static TreeMap<String, Double> m = new TreeMap<>();
    static double N;
 
    static void func() {
        StringBuffer sb = new StringBuffer();
        for (Entry<String, Double> e : m.entrySet()) {
            sb.append(e.getKey() + " " + String.format("%.4f", e.getValue() * 100.0 / N) + "\n");
        }
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        while (true) {
            st = br.readLine();
            if (st == null || st.length() == 0)
                break;
 
            if (m.containsKey(st)) {
                double a = m.get(st);
 
                m.put(st, a + 1.0);
            } else {
                m.put(st, 1.0);
            }
 
            N += 1.0;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 1874 수택 수열  (0) 2021.01.25
boj 17298 오큰수  (0) 2021.01.25
boj 5639 이진 검색 트리  (0) 2021.01.24
boj 1991 트리 순회  (0) 2021.01.22
boj 11003 최솟값 찾기  (0) 2021.01.22

www.acmicpc.net/problem/5639

 

5639번: 이진 검색 트리

트리를 전위 순회한 결과가 주어진다. 노드에 들어있는 키의 값은 106보다 작은 양의 정수이다. 모든 값은 한 줄에 하나씩 주어지며, 노드의 수는 10,000개 이하이다. 같은 키를 가지는 노드는 없다

www.acmicpc.net

자바로 트리를 처음 구현해보았습니다..

 

입력이 전위순회이므로 들어오는 대로 트리에 넣어줍니다.

이진 검색 트리는 x가 들어오면 트리의 루트노드의 값부터 비교를 합니다.

노드의 값보다 작으면 왼쪽 서브트리이고,

노드의 값보다 크면 오른쪽 서브트리로 이동하면 되고

 

이동하려는 서브트리가 null이면 그곳에 newnode를 삽입하면 됩니다.

출력은 후위순회로 출력입니다.

 

 

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import java.io.BufferedReader;
import java.io.InputStreamReader;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringBuffer sb = new StringBuffer();
 
    static class tree {
        int x;
        tree llink;
        tree rlink;
 
        tree() {
        }
 
        tree(int x, tree llink, tree rlink) {
            this.x = x;
            this.llink = llink;
            this.rlink = rlink;
        }
    }
 
    static tree node = new tree();
 
    static void addnode(int x) {
        tree newnode = new tree(x, nullnull);
 
        if (node.x == 0) {
            node.x = x;
            return;
        }
 
        tree p = node;
 
        while (p != null) {
            if (p.x > x) {
                if (p.llink == null) {
                    p.llink = newnode;
                    break;
                } else
                    p = p.llink;
            } else {
                if (p.rlink == null) {
                    p.rlink = newnode;
                    break;
                } else
                    p = p.rlink;
            }
        }
    }
 
    static void postorder(tree t) {
        if (t.llink != null)
            postorder(t.llink);
        if (t.rlink != null)
            postorder(t.rlink);
        sb.append(t.x + "\n");
    }
 
    static void input() throws Exception {
        String st;
        while (true) {
            st = br.readLine();
            if (st == null || st.length() == 0)
                break;
 
            int x = Integer.parseInt(st);
            addnode(x);
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        postorder(node);
        System.out.println(sb.toString());
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 17298 오큰수  (0) 2021.01.25
boj 4358 생태학  (0) 2021.01.25
boj 1991 트리 순회  (0) 2021.01.22
boj 11003 최솟값 찾기  (0) 2021.01.22
boj 1517 버블 소트  (0) 2021.01.22

www.acmicpc.net/problem/1991

 

1991번: 트리 순회

첫째 줄에는 이진 트리의 노드의 개수 N(1≤N≤26)이 주어진다. 둘째 줄부터 N개의 줄에 걸쳐 각 노드와 그의 왼쪽 자식 노드, 오른쪽 자식 노드가 주어진다. 노드의 이름은 A부터 차례대로 영문자

www.acmicpc.net

트리 순회의 간단한 문제입니다.

 

input으로 주어지는 노드는 A~Z까지 26개이므로 숫자로 변환하여 인덱스화 하였습니다.

list배열에 각 노드의 왼쪽자식을 [0]에, 오른쪽 자식을 [1]에 저장하여 순회하였습니다.

 

 

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package BOJ.data_structure;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Boj1991 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static int list[][] = new int[27][2];
    static int N;
 
    static void preorder(int v) {
        sb.append((char) (v + 'A'));
        if (list[v][0!= -1)
            preorder(list[v][0]);
        if (list[v][1!= -1)
            preorder(list[v][1]);
    }
 
    static void inorder(int v) {
        if (list[v][0!= -1)
            inorder(list[v][0]);
        sb.append((char) (v + 'A'));
        if (list[v][1!= -1)
            inorder(list[v][1]);
    }
 
    static void postorder(int v) {
        if (list[v][0!= -1)
            postorder(list[v][0]);
        if (list[v][1!= -1)
            postorder(list[v][1]);
        sb.append((char) (v + 'A'));
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            char x = st.nextToken().charAt(0);
            char l = st.nextToken().charAt(0);
            char r = st.nextToken().charAt(0);
 
            if (l == '.')
                list[x - 'A'][0= -1;
            else
                list[x - 'A'][0= l - 'A';
 
            if (r == '.')
                list[x - 'A'][1= -1;
            else
                list[x - 'A'][1= r - 'A';
 
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        preorder(0);
        sb.append("\n");
        inorder(0);
        sb.append("\n");
        postorder(0);
        sb.append("\n");
        System.out.println(sb.toString());
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 4358 생태학  (0) 2021.01.25
boj 5639 이진 검색 트리  (0) 2021.01.24
boj 11003 최솟값 찾기  (0) 2021.01.22
boj 1517 버블 소트  (0) 2021.01.22
boj 2517 달리기  (0) 2021.01.22

https://www.acmicpc.net/problem/11003

 

11003번: 최솟값 찾기

N개의 수 A1, A2, ..., AN과 L이 주어진다. Di = Ai-L+1 ~ Ai 중의 최솟값이라고 할 때, D에 저장된 수를 출력하는 프로그램을 작성하시오. 이때, i ≤ 0 인 Ai는 무시하고 D를 구해야 한다.

www.acmicpc.net

A[i-L+1]~A[i] 중 최솟값을 구하는 문제로 Deque를 이용하여 해결하였습니다.

 

큐가 비어있을 때는 바로 삽입하면 되고

반복문을 이용하여 삽입하려는 수가 큐의 뒤에있는 수보다 작을때마다 뒤의 값을 제거한 후에 삽입합니다.

 

만약 A[i-L+1]이 양수가 되면 큐의 앞에있는 수가 제거되었는지 확인하고 제거되지 않았으면 제거합니다.

그럼 큐의 맨앞에 있는 수가 최솟값이므로 ans배열에 넣으면 됩니다.

 

 

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Deque;
import java.util.LinkedList;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[], ans[];
    static int N, L;
 
    static void func() {
        Deque<Integer> dq = new LinkedList<>();
        for (int i = 0; i < N; i++) {
            if (dq.isEmpty())
                dq.addLast(list[i]);
            else {
                while (true) {
                    if (dq.isEmpty())
                        break;
                    if (dq.peekLast() > list[i])
                        dq.removeLast();
                    else
                        break;
                }
 
                dq.addLast(list[i]);
            }
 
            if (L <= i) {
                if (dq.peek() == list[i - L])
                    dq.removeFirst();
            }
 
            ans[i] = dq.peek();
        }
    }
 
    static void print() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < N; i++) {
            sb.append(ans[i] + " ");
        }
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
 
        N = Integer.parseInt(st.nextToken());
        list = new int[N];
        ans = new int[N];
        L = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 5639 이진 검색 트리  (0) 2021.01.24
boj 1991 트리 순회  (0) 2021.01.22
boj 1517 버블 소트  (0) 2021.01.22
boj 2517 달리기  (0) 2021.01.22
boj 3425 고스택  (0) 2021.01.22

https://www.acmicpc.net/problem/1517

 

1517번: 버블 소트

첫째 줄에 N(1≤N≤500,000)이 주어진다. 다음 줄에는 N개의 정수로 A[1], A[2], …, A[N]이 주어진다. 각각의 A[i]는 0≤|A[i]|≤1,000,000,000의 범위에 들어있다.

www.acmicpc.net

문제는 버블 소트이지만 머지 소트를 이용하여 해결할 수 있습니다.

머지 소트 과정에서 뒤에있는 인덱스가 앞으로 올 때 이동한 만큼 더해주면 됩니다.

 

 

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[], sorted[];
    static int N;
    static long ans;
 
    static void mergesort(int l, int m, int r) {
        int i = l;
        int k = l;
        int j = m + 1;
 
        while (i <= m && j <= r) {
            if (list[i] <= list[j]) {
                sorted[k] = list[i];
                i++;
            } else {
                if (list[k] != list[j])
                    ans += (j - k);
                sorted[k] = list[j];
                j++;
            }
            k++;
        }
 
        if (i > m) {
            for (; j <= r; j++, k++) {
                sorted[k] = list[j];
            }
        } else {
            for (; i <= m; i++, k++) {
                sorted[k] = list[i];
            }
        }
 
        for (int t = l; t <= r; t++) {
            list[t] = sorted[t];
        }
    }
 
    static void merge(int l, int r) {
        if (l != r) {
            int m = (l + r) / 2;
 
            merge(l, m);
            merge(m + 1, r);
            mergesort(l, m, r);
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N];
        sorted = new int[N];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        merge(0, N - 1);
        System.out.println(ans);
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 5639 이진 검색 트리  (0) 2021.01.24
boj 1991 트리 순회  (0) 2021.01.22
boj 11003 최솟값 찾기  (0) 2021.01.22
boj 2517 달리기  (0) 2021.01.22
boj 3425 고스택  (0) 2021.01.22

https://www.acmicpc.net/problem/2517

 

2517번: 달리기

첫째 줄에는 선수의 수를 의미하는 정수 N이 주어진다. N은 3 이상 500,000 이하이다. 이후 N개의 줄에는 정수가 한 줄에 하나씩 주어진다. 이 값들은 각 선수들의 평소 실력을 앞에서 달리고 있는

www.acmicpc.net

자신 앞에 있는 사람들 중 자신보다 실력이 더 낮은 사람이 몇 명인지 구하는 문제입니다.

이 문제는 두 가지 방법으로 해결하였습니다.

예전에 배운적 있었던 Merge Sort방법과 이 문제의 풀이방법으로 명시되어 있는 Segment Tree 방법으로 문제를 두번 풀어보았습니다.

 

먼저 Merge Sort 방법입니다.

평소의 Merge Sort를 사용했던 것처럼 i번과 j번을 서로 비교해가며 큰 값을 sorted[k]에 저장하는 방식입니다.

 

여기서 기존의 Merge Sort에 추가해야 할 것이 하나 있는데

i번은 앞의 인덱스, j번은 뒤의 인덱스 이므로 j번 인덱스의 값이 앞으로 이동하게 되면 그 차이만큼 rank에서 빼줍니다. (i번이 뒤로가는 것은 무시하셔도 됩니다.)

 

 

C++로 구현한 merge sort방식
JAVA로 구현한 merge sort방식

 

작년에 C++로 동일한 방식으로 해결하였으나 java에서는 TLE를 받았는데

아는 형님께서 StringBuilder라는 것을 알려주셨고, 출력 부분에 이것만 추가하니 AC를 받았습니다.

StringBuilder를 이제 자주 써야겠다는 생각이 드는군요 ㅎㅎ

오늘도 하나 배워갑니다..

 

 

[Merge Sort]

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[][], rank[], sorted[][];
 
    static int N;
 
    static void mergesort(int l, int m, int r) {
        int i = l;
        int k = l;
        int j = m + 1;
 
        while (i <= m && j <= r) {
            if (list[i][0> list[j][0]) {
                sorted[k][0= list[i][0];
                sorted[k][1= list[i][1];
 
                i++;
                k++;
            } else {
                sorted[k][0= list[j][0];
                sorted[k][1= list[j][1];
 
                rank[list[j][1]] -= (j - k);
 
                j++;
                k++;
            }
        }
 
        if (i > m) {
            for (; j <= r; j++, k++) {
                sorted[k][0= list[j][0];
                sorted[k][1= list[j][1];
            }
        } else if (j > r) {
            for (; i <= m; i++, k++) {
                sorted[k][0= list[i][0];
                sorted[k][1= list[i][1];
            }
        }
 
        for (int t = l; t <= r; t++) {
            list[t][0= sorted[t][0];
            list[t][1= sorted[t][1];
        }
    }
 
    static void merge(int l, int r) {
        if (l != r) {
            int m = (l + r) / 2;
            merge(l, m);
            merge(m + 1, r);
            mergesort(l, m, r);
        }
    }
 
    static void print() {
        StringBuilder sb = new StringBuilder();
        
        for (int i = 1; i <= N; i++) {
            sb.append(rank[i]+"\n");
        }
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N + 1][2];
        sorted = new int[N + 1][2];
        rank = new int[N + 1];
 
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i][0= Integer.parseInt(st.nextToken());
            list[i][1= i;
            rank[i] = i;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        merge(1, N);
        print();
    }
}
cs

 

다음은 Segment Tree 방식입니다.

이 방식은 구간 합을 구하는 방식으로 해결할 수 있습니다.

먼저 list 배열을 실력의 오름차순으로 정렬한 후, 순서대로 인덱스를 트리에 저장해주시면 됩니다.

 

실력 순으로 query 후 update를 진행하기 때문에 query로 트리를 탐색할 때는 모든 값들이 자신보다 실력이 낮은 값들입니다.

여기서 인덱스가 자신보다 앞에 있는 갯수만 찾으시면 됩니다..

 

merge sort방식으로 구현
segment tree방식으로 구현

문제에 명시되어있는 풀이방법은 Segment Tree인데 Merge Sort방식으로 풀이한게 더 빠른 시간이 나왔습니다.

제가 로직을 잘못 구현했을 수도 있지만 여러방식으로 시도해봐야겠습니다..

 

 

[Segment Tree]

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[][], tree[], rank[];
    static int N;
 
    static int query(int node, int s, int e, int l, int r) {
        if (l <= s && e <= r)
            return tree[node];
        if (s > r || e < l)
            return 0;
 
        int m = (s + e) / 2;
        return query(node * 2, s, m, l, r) + query(node * 2 + 1, m + 1, e, l, r);
    }
 
    static void update(int node, int s, int e, int idx) {
        if (idx < s || idx > e)
            return;
 
        tree[node]++;
        int m = (s + e) / 2;
        if (s != e) {
            update(node * 2, s, m, idx);
            update(node * 2 + 1, m + 1, e, idx);
        }
    }
 
    static void func() {
        StringBuffer sb = new StringBuffer();
        for (int i = 1; i <= N; i++) {
            int ans = query(11, N, 1, list[i][1]);
 
            rank[list[i][1]] = list[i][1- ans;
            update(11, N, list[i][1]);
        }
 
        for (int i = 1; i <= N; i++) {
            sb.append(rank[i]+"\n");
        }
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N + 1][2];
        rank = new int[N + 1];
        tree = new int[N * 4];
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i][0= Integer.parseInt(st.nextToken());
            list[i][1= i;
        }
 
        Arrays.sort(list, new Comparator<int[]>() {
            public int compare(int[] a, int[] b) {
                if (a[0> b[0])
                    return 1;
                else
                    return -1;
            }
        });
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 5639 이진 검색 트리  (0) 2021.01.24
boj 1991 트리 순회  (0) 2021.01.22
boj 11003 최솟값 찾기  (0) 2021.01.22
boj 1517 버블 소트  (0) 2021.01.22
boj 3425 고스택  (0) 2021.01.22

 

https://www.acmicpc.net/problem/3425

 

3425번: 고스택

각각의 입력값에 대해서, 해당하는 프로그램을 수행한 뒤, 출력값을 출력하면 된다. 출력값이란 스택에 저장되어 있는 숫자이다. 만약, 프로그램 에러가 발생하거나, 모든 수행이 종료됐을 때

www.acmicpc.net

[이 문제에서 수행하는 연산]

NUM X : X를 스택의 가장 위에 저장

POP : 스택 가장 위의 숫자를 제거

INV : 첫 번째 수의 부호를 변경

DUP : 첫 번째 수를 스택의 가장위에 한번 더 저장

SWP : 첫 번째 수와 두 번째 수의 위치를 변경

ADD : 첫 번째 수 + 두 번째 수

SUB : 두 번째 수 - 첫 번째 수

MUL : 첫 번째 수 * 두 번째 수

DIV : 두 번째 수 / 첫 번째 수

MOD : 두 번째 수 % 첫 번째 수

 

위의 연산들이 랜덤으로 주어지고, 입력값 V가 주어질 때마다 이 연산들을 수행한 결과를 출력합니다.

 

문제에서 요구하는 조건을 종합하면

1. 숫자가 부족해서 연산수행을 하지 못할 때

2. DIV, MOD 연산 시 0으로 나눴을 때

3. 연산 결과의 절댓값이 109 보다 클 때

4. 모든 연산이 종료되었을 때 스택에 저장되어 있는 숫자가 1개가 아닐 때

라고 할 수 있고, 그럼 출력값의 조건으로는

 

모든 연산이 종료되었을 때 스택에 저장되어 있는 숫자가 1개이고 절댓값이 109보다 작거나 같을 때 입니다.

 

나머지는 연산이 요구하는대로 계산해 주시면 됩니다.

 

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Stack;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br;
    static StringTokenizer st;
    static String type;
    static ArrayList<String[]> list = new ArrayList<>();
    static Stack<long[]> stack = new Stack<>();
    static long N;
    static final long INF = 1000000000;
 
    static boolean func() {
        stack.push(new long[] {N});
        for (String[] arr : list) {
            if ("NUM".equals(arr[0])) {
                stack.push(new long[] {Long.parseLong(arr[1])});
            } else if ("POP".equals(arr[0])) {
                if (stack.isEmpty())
                    return false;
                stack.pop();
            } else if ("INV".equals(arr[0])) {
                if (stack.isEmpty())
                    return false;
                long a = stack.peek()[0];
                stack.pop();
                stack.push(new long[] {-a});
            } else if ("DUP".equals(arr[0])) {
                if (stack.isEmpty())
                    return false;
                stack.push(stack.peek());
            } else if ("SWP".equals(arr[0])) {
                if (stack.size() < 2)
                    return false;
                long num1 = stack.peek()[0];
                stack.pop();
                long num2 = stack.peek()[0];
                stack.pop();
                stack.push(new long[] {num1});
                stack.push(new long[] {num2});
            } else if ("ADD".equals(arr[0])) {
                if (stack.size() < 2)
                    return false;
                long num1 = stack.peek()[0];
                stack.pop();
                long num2 = stack.peek()[0];
                stack.pop();
                stack.push(new long[] {num1+num2});
            } else if ("SUB".equals(arr[0])) {
                if (stack.size() < 2)
                    return false;
                long num1 = stack.peek()[0];
                stack.pop();
                long num2 = stack.peek()[0];
                stack.pop();
                stack.push(new long[] {num2-num1});
            } else if ("MUL".equals(arr[0])) {
                if (stack.size() < 2)
                    return false;
                long num1 = stack.peek()[0];
                stack.pop();
                long num2 = stack.peek()[0];
                stack.pop();
                stack.push(new long[] {num1*num2});
            } else if ("DIV".equals(arr[0])) {
                if (stack.size() < 2)
                    return false;
                long num1 = stack.peek()[0];
                stack.pop();
                if (num1 == 0)
                    return false;
                long num2 = stack.peek()[0];
                stack.pop();
                stack.push(new long[] {num2/num1});
            } else if ("MOD".equals(arr[0])) {
                if (stack.size() < 2)
                    return false;
                long num1 = stack.peek()[0];
                stack.pop();
                if (num1 == 0)
                    return false;
                long num2 = stack.peek()[0];
                stack.pop();
                stack.push(new long[] {num2%num1});
            }
        }
        
        return true;
    }
 
    static void numinput() throws Exception {
        boolean chk = false;
        st = new StringTokenizer(br.readLine());
 
        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            st = new StringTokenizer(br.readLine());
 
            N = Long.parseLong(st.nextToken());
            chk = func();
            if (!chk || stack.size() != 1) {
                System.out.println("ERROR");
            } else {
                if(Math.abs(stack.peek()[0])>INF)
                    System.out.println("ERROR");    
                else
                    System.out.println(stack.peek()[0]);
            }
 
            while (!stack.isEmpty())
                stack.pop();
        }
        
        while(!list.isEmpty())
            list.remove(0);
    }
 
    static void typeinput() throws Exception {
        while (true) {
            st = new StringTokenizer(br.readLine());
 
            type = st.nextToken();
            if ("NUM".equals(type)) {
                String num = st.nextToken();
                list.add(new String[] { type, num });
            } else if ("END".equals(type) || "QUIT".equals(type)) {
                break;
            } else {
                list.add(new String[] { type });
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        br = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            typeinput();
            if ("QUIT".equals(type))
                break;
            numinput();
            st = new StringTokenizer(br.readLine());
            System.out.println();
        }
    }
}
 
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 5639 이진 검색 트리  (0) 2021.01.24
boj 1991 트리 순회  (0) 2021.01.22
boj 11003 최솟값 찾기  (0) 2021.01.22
boj 1517 버블 소트  (0) 2021.01.22
boj 2517 달리기  (0) 2021.01.22

+ Recent posts