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

 

15926번: 현욱은 괄호왕이야!!

첫 번째 입출력에서, 맨 처음 위치부터 4개를 잘라낸 (())가 가장 긴 올바른 괄호 문자열이다. 두 번째 입출력에서, 6번째 위치부터 8개를 잘라낸 ()((()))가 가장 긴 올바른 괄호 문자열이다.

www.acmicpc.net

주어진 입력에서 올바른 괄호쌍의 부분 문자열이 가장 긴 길이를 구하는 문제입니다.

올바른 괄호쌍을 구하기 위해서는 stack을 이용합니다.

 

기본 스택문제와 동일하게 `(`가 나오면 stack에 push, `)`가 나오면 stack에서 pop 연산을 수행합니다.

이 문제는 주어진 문자열의 인덱스를 이용합니다.

`(`가 나오면 그 인덱스를 stack에 push합니다.

`)`가 나오면 s.top의 인덱스와 현재 인덱스에 true 값을 넣습니다.

 

최종으로는 chk[i] = true인 부분의 max 길이를 구해주시면 되겠습니다.

 

 

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
#include <iostream>
#include <string>
#include <stack>
#include <algorithm>
#define MAX 200001
using namespace std;
 
string str;
bool chk[MAX];
int N;
 
void func() {
    stack<int> s;
    for (int i = 0; i < N; i++) {
        if (str[i] == '(') {
            s.push(i);
        }
        else {
            if (s.empty()) continue;
 
            chk[i] = chk[s.top()] = true;
            s.pop();
        }
    }
 
    int ret = 0;
    int conn = chk[0];
    for (int i = 1; i < N; i++) {
        if (chk[i]) conn++;
        else conn = 0;
 
        ret = max(ret, conn);
    }
 
    cout << ret << '\n';
}
 
void input() {
    cin >> N >> str;
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

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

boj 21939 문제 추천 시스템 Version 1  (0) 2022.02.11
boj 17299 오등큰수  (0) 2021.02.22
boj 9372 상근이의 여행  (0) 2021.02.09
boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05

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

 

21939번: 문제 추천 시스템 Version 1

tony9402는 최근 깃헙에 코딩테스트 대비 문제를 직접 뽑아서 "문제 번호, 난이도"로 정리해놨다. 깃헙을 이용하여 공부하시는 분들을 위해 새로운 기능을 추가해보려고 한다. 만들려고 하는 명령

www.acmicpc.net

recommend x

x가 1인 경우 리스트에서 가장 어려운 문제의 번호를 출력, 가장 어려운 문제가 여러 개면 문제 번호가 큰 것을 출력

x가 -1인 경우 리스트에서 가장 쉬운 문제의 번호를 출력, 가장 어려운 문제가 여러 개면 문제 번호가 작은 것을 출력

 

add P L

리스트에 난이도가 L인 문제 번호 P를 추가한다.

현재 리스트에 없는 문제만 들어오며, 이미 해결하여 리스트에서 제외된 문제가 다시 들어올 수 있다.

 

solved P

리스트에서 문제 번호 P를 제거한다. (해결한 것으로 간주)

 

문제들은 [문제 번호, 난이도] 로 정리되어 있으며, 들어온 순서대로 명령을 처리하는 문제입니다.

recommend 명령어에서 난이도가 가장 어려운 문제와 가장 쉬운 문제를 빠르게 뽑아내야 하므로 우선 순위 큐를 2개 사용하며, 최대 우선순위 큐와 최소 우선순위 큐를 같이 관리합니다.

 

각 문제의 난이도를 나타내기 위해 levellist라는 배열을 사용하였으며, 값이 0이 아니라면 리스트에 있는 문제라는 뜻입니다.

이를 이용하여 solved 시 levellist의 값을 0으로 바꾸고, recommend 명령어가 들어왔을 때 출력하기 전에 현재 최대/최소 우선순위 큐에 이미 solved된 문제가 있는지 확인하는 작업을 거친 후에 출력하도록 합니다.

 

 

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
#include <iostream>
#include <queue>
#include <algorithm>
#include <set>
#include <string>
#define MAX 100001
using namespace std;
typedef pair<intint> pi;
 
priority_queue<pi, vector<pi>, less<pi> > mxq;
priority_queue<pi, vector<pi>, greater<pi> > mnq;
int levellist[MAX];
int N, M;
 
void func() {
    string type;
    int x, y;
    cin >> M;
    while (M--) {
        cin >> type;
        if (type == "add") {
            cin >> x >> y;
            mxq.push({ y,x });
            mnq.push({ y,x });
            levellist[x] = y;
        }
        else {
            cin >> x;
            if (type == "recommend") {
                if (x == 1) {
                    while (1) {
                        int p = mxq.top().second;
                        int l = mxq.top().first;
                        if (levellist[p] == l) break;
                        mxq.pop();
                    }
 
                    cout << mxq.top().second << '\n';
                }
                else {
                    while (1) {
                        int p = mnq.top().second;
                        int l = mnq.top().first;
                        if (levellist[p] == l) break;
                        mnq.pop();
                    }
 
                    cout << mnq.top().second << '\n';
                }
            }
            else {
                levellist[x] = 0;
            }
        }
    }
}
 
void input() {
    int P, L;
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> P >> L;
        mxq.push({ L,P });
        mnq.push({ L,P });
        levellist[P] = L;
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
    
    return 0;
}
cs

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

boj 15926 현욱은 괄호왕이야!!  (1) 2023.07.24
boj 17299 오등큰수  (0) 2021.02.22
boj 9372 상근이의 여행  (0) 2021.02.09
boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05

www.acmicpc.net/problem/17299

 

17299번: 오등큰수

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

www.acmicpc.net

emoney96.tistory.com/49

 

boj 17298 오큰수

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 스..

emoney96.tistory.com

위의 문제와 같은 문제입니다.

오큰수는 오른쪽에 있는 자신보다 큰 수 중에 가장 왼쪽에 있는 수를 출력하는 문제이고, 

이 문제는 오른쪽에 있는 자신보다 등장횟수가 많은 수 중에 가장 왼쪽에 있는 수를 출력하는 문제입니다.

자신보다 큰 수 -> 자신보다 등장횟수가 많은 수 의 차이이며 풀이는 같습니다.

 

이 문제 역시 수열을 역순으로 탐색하였고,

list[i]를 스택에 넣기 전에 자신보다 등장횟수가 적은 값들을 모두 pop해줍니다.

 

스택이 비어있으면 -1, 아니면 top을 출력해주시면 됩니다.

 

 

[C++]

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
#include <iostream>
#include <stack>
using namespace std;
 
stack<int> s;
int list[1000001], num[1000001], ans[1000001];
int N;
 
void print() {
    for (int i = 1; i <= N; i++) {
        cout << ans[i] << ' ';
    }
 
    cout << '\n';
}
 
void func() {
    for (int i = N; i > 0; i--) {
        while (!s.empty() && num[list[i]] >= num[s.top()]) s.pop();
 
        if (s.empty()) ans[i] = -1;
        else ans[i] = s.top();
 
        s.push(list[i]);
    }
}
 
void input() {
    cin >> N;
    for (int i = 1; i <= N; i++) {
        cin >> list[i];
        num[list[i]]++;
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
    print();
 
    return 0;
}
cs

 

 

[Java]

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 Stack<Integer> s = new Stack<>();
    static int list[], num[], ans[];
    static int N;
 
    static void print() {
        StringBuffer sb = new StringBuffer();
        for (int i = 1; i <= N; i++)
            sb.append(ans[i]).append(" ");
        System.out.println(sb.toString());
    }
 
    static void func() {
        for (int i = N; i > 0; i--) {
            while (!s.isEmpty() && num[list[i]] >= num[s.peek()])
                s.pop();
 
            if (s.isEmpty())
                ans[i] = -1;
            else
                ans[i] = s.peek();
 
            s.push(list[i]);
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N + 1];
        num = new int[1000001];
        ans = new int[1000001];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
            num[list[i]]++;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

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

boj 15926 현욱은 괄호왕이야!!  (1) 2023.07.24
boj 21939 문제 추천 시스템 Version 1  (0) 2022.02.11
boj 9372 상근이의 여행  (0) 2021.02.09
boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05

www.acmicpc.net/problem/9372

 

9372번: 상근이의 여행

첫 번째 줄에는 테스트 케이스의 수 T(T ≤ 100)가 주어지고, 각 테스트 케이스마다 다음과 같은 정보가 주어진다. 첫 번째 줄에는 국가의 수 N(2 ≤ N ≤ 1 000)과 비행기의 종류 M(1 ≤ M ≤ 10 000) 가

www.acmicpc.net

이문제는 모든 국가를 여행하는데 타야하는 비행기의 최소 갯수를 출력하는 문제입니다.

입력으로는 무조건 연결그래프만 주어지며, N개의 국가를 모두 연결하기 위해서는 최소 N - 1개의 간선만 있으면 됩니다.

입력만 다받고 N - 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
package BOJ.data_structure;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Boj9372 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static int N;
 
    static void input() throws Exception {
        int M, x;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        while (M-- > 0) {
            st = new StringTokenizer(br.readLine());
            x = Integer.parseInt(st.nextToken());
            x = Integer.parseInt(st.nextToken());
        }
 
        sb.append(N - 1 + "\n");
    }
 
    public static void main(String[] args) throws Exception {
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            input();
        }
        
        System.out.println(sb.toString());
    }
}
cs

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

boj 21939 문제 추천 시스템 Version 1  (0) 2022.02.11
boj 17299 오등큰수  (0) 2021.02.22
boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05
boj 1935 후위 표기식2  (0) 2021.02.05

www.acmicpc.net/problem/1158

 

1158번: 요세푸스 문제

첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)

www.acmicpc.net

1 ~ N 까지 순서대로 저장되어있으면 매번 K번째 수를 제거하고, 제거되는 숫자 순서대로 출력하는 문제입니다.

 

저는 덱을 이용하여 1 ~ N 까지의 숫자를 넣었고, K번째 수를 제거하기 위해 1 ~ K - 1번째 수를 뒤로 보낸 후에 제거하였습니다.

 

원래 큐를 이용하는 문제지만 저는 덱이 먼저 떠올라서 덱으로 풀었습니다.

하지만 이유는 모르겠으나 메모리와 시간 차이가 있었습니다.

Queue를 이용한 풀이

 

Deque를 이용한 풀이

무슨 이유일까요... 소스 두개모두 올립니다...

아마 ArrayDeque와 LinkedList의 차이인것 같습니다..

LinkedList가 좌 우를 연결하는 link를 다루기때문에 이에대한 추가 메모리 발생과 link 연결을 위한 연산시간이 추가로 발생하는게 아닌가하는 생각이 듭니다.

 

 

[Queue]

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.LinkedList;
import java.util.Queue;
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 Queue<Integer> q = new LinkedList<>();
    static int N, K;
 
    static void func() {
        sb.append("<");
        while (!q.isEmpty()) {
            for (int i = 0; i < K - 1; i++) {
                q.add(q.poll());
            }
 
            sb.append(q.poll());
            if (!q.isEmpty())
                sb.append(", ");
        }
        sb.append(">");
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
 
        for (int i = 1; i <= N; i++)
            q.add(i);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

 

 

[Deque]

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.ArrayDeque;
import java.util.Deque;
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 Deque<Integer> dq = new ArrayDeque<>();
    static int N, K;
 
    static void func() {
        sb.append("<");
        while (!dq.isEmpty()) {
            for (int i = 0; i < K - 1; i++) {
                dq.addLast(dq.pollFirst());
            }
 
            sb.append(dq.pollFirst());
            if (!dq.isEmpty())
                sb.append(", ");
        }
        sb.append(">");
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
 
        for (int i = 1; i <= N; i++)
            dq.addLast(i);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 17299 오등큰수  (0) 2021.02.22
boj 9372 상근이의 여행  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05
boj 1935 후위 표기식2  (0) 2021.02.05
boj 2493 탑  (0) 2021.02.04

www.acmicpc.net/problem/1918

 

1918번: 후위 표기식

첫째 줄에 중위 표기식이 주어진다. 단 이 수식의 피연산자는 A~Z의 문자로 이루어지며 수식에서 한 번씩만 등장한다. 그리고 -A+B와 같이 -가 가장 앞에 오거나 AB와 같이 *가 생략되는 등의 수식

www.acmicpc.net

입력은 중위 표기식으로 주어지고 후위 표기식으로 출력하는 문제입니다.

 

우선 A ~ Z까지의 문자는 바로 출력입니다.

'('는 스택에 바로 push하시면 되고

')'가 나오면 스택에 '('가 나올때까지 pop한 것을 출력해줍니다.

+, -가 나오면 자신보다 우선순위가 낮은 연산자가 없으므로 괄호를 만날때까지 pop한 것을 출력해줍니다.

*, /가 나오면 자신보다 우선순위가 낮은 +, -가 나오거나 괄호를 만날때까지 pop한 것을 출력해줍니다.

마지막에 남아있는 연산자를 모두 출력합니다.

 

 

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
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<Character> s = new Stack<>();
    static char ch[];
 
    static void func() {
        for (char x : ch) {
            if ('A' <= x && x <= 'Z')
                sb.append(x);
            else if (x == '(')
                s.push(x);
            else if (x == ')') {
                while (s.peek() != '(')
                    sb.append(s.pop());
                s.pop();
            } else if (x == '+' || x == '-') {
                while (!s.isEmpty() && s.peek() != '(')
                    sb.append(s.pop());
                s.push(x);
            } else {
                while (!s.isEmpty() && (s.peek() == '*' || s.peek() == '/'))
                    sb.append(s.pop());
                s.push(x);
            }
        }
 
        while (!s.isEmpty())
            sb.append(s.pop());
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        ch = st.nextToken().toCharArray();
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 9372 상근이의 여행  (0) 2021.02.09
boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1935 후위 표기식2  (0) 2021.02.05
boj 2493 탑  (0) 2021.02.04
boj 6416 트리인가?  (0) 2021.02.04

www.acmicpc.net/problem/1935

 

1935번: 후위 표기식2

첫째 줄에 피연산자의 개수(1 ≤ N ≤ 26) 가 주어진다. 그리고 둘째 줄에는 후위 표기식이 주어진다. (여기서 피연산자는 A~Z의 영대문자이며, A부터 순서대로 N개의 영대문자만이 사용되며, 길이

www.acmicpc.net

피연산자가 문자로 주어진 후위표기식이 입력으로 들어오면 이를 계산한 결과를 소수 둘째 자리까지 출력하는 문제입니다.

우선 피연산자에 대응하는 값은 alphabet 배열에 넣어서 alphabet[ch-'A']와 같이 사용하였습니다.

 

A ~ Z가 오면 스택에 대응하는 값을 넣고, 연산자가 오면 두개를 꺼내서 계산한 값을 스택에 넣었습니다.

마지막에 스택에 들어있는 값은 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
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 Stack<Double> s = new Stack<>();
    static char ch[];
    static double alphabet[] = new double[26];
    static int N;
 
    static void func() {
        for (char x : ch) {
            if ('A' <= x && x <= 'Z')
                s.push(alphabet[x - 'A']);
            else if (x == '+') {
                double a = s.pop();
                double b = s.pop();
                s.push(b + a);
            } else if (x == '-') {
                double a = s.pop();
                double b = s.pop();
                s.push(b - a);
            } else if (x == '*') {
                double a = s.pop();
                double b = s.pop();
                s.push(b * a);
            } else {
                double a = s.pop();
                double b = s.pop();
                s.push(b / a);
            }
        }
 
        System.out.printf("%.2f\n", s.pop());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        ch = st.nextToken().toCharArray();
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            alphabet[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05
boj 2493 탑  (0) 2021.02.04
boj 6416 트리인가?  (0) 2021.02.04
boj 3190 뱀  (0) 2021.02.02

www.acmicpc.net/problem/2493

 

2493번: 탑

첫째 줄에 탑의 수를 나타내는 정수 N이 주어진다. N은 1 이상 500,000 이하이다. 둘째 줄에는 N개의 탑들의 높이가 직선상에 놓인 순서대로 하나의 빈칸을 사이에 두고 주어진다. 탑들의 높이는 1

www.acmicpc.net

탑 A의 왼쪽에 있는 탑들 중에서 탑 A보다 더 큰 높이의 탑들 중 가장 오른쪽의 탑의 위치를 구하는 문제입니다.

배열크기를 너무 높게잡으면 메모리초과까지 나올 수 있어서 초기에 배열크기를 잘 잡아야합니다.

N이 500000까지 들어오기때문에 N^2으로는 무조건 시간초과뜹니다

 

먼저 입력으로 주어지는 탑의 높이를 list에 저장하였고, 1번부터 N번까지 순회를 합니다.

 

스택에는 인덱스를 유지합니다.

i번 위치에서 스택이 비어있지 않고, list[top]이 list[i]보다 작을동안 pop을 해줍니다.

그 후에 스택이 비어있으면 0, 아니면 스택의 top을 출력하시면 됩니다.

 

 

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
package BOJ.data_structure;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
 
public class Boj2493 {
    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[];
    static int N;
 
    static void func() {
        for (int i = 0; i < N; i++) {
            while (!s.isEmpty() && list[s.peek()] < list[i])
                s.pop();
 
            if (s.isEmpty()) {
                s.push(i);
                sb.append("0 ");
            } else {
                sb.append(s.peek() + 1 + " ");
                s.push(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];
 
        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();
    }
}
cs

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

boj 1918 후위 표기식  (0) 2021.02.05
boj 1935 후위 표기식2  (0) 2021.02.05
boj 6416 트리인가?  (0) 2021.02.04
boj 3190 뱀  (0) 2021.02.02
boj 2346 풍선 터뜨리기  (0) 2021.02.02

www.acmicpc.net/problem/6416

 

6416번: 트리인가?

트리는 굉장히 잘 알려진 자료 구조이다. 트리를 만족하는 자료 구조는 비어 있거나(노드의 개수가 0개), 노드의 개수가 1개 이상이고 방향 간선이 존재하며 다음과 같은 조건을 만족해야 한다.

www.acmicpc.net

자바라서 입력 받는거부터 좀 힘들었습니다..

다행히 검색으로 다음 토큰이 있는지 확인하는 st.hasMoreTokens() 라는 것을 찾아서 입력을 받았습니다.

 

이 문제는 u v 로 입력이 주어지고 이는 u->v를 뜻합니다.

트리이기 때문에 방향 그래프이고 한 방향으로만 향합니다. 즉, v->u는 안됩니다.

 

이 문제에서는 트리가 아닌 조건들을 모두 체크해주어야합니다.

1. 부모노드가 2개 이상인지

2. 루트노드가 1개가 아닌지 (0개이거나 2개 이상인지)

3. 사이클이 있는지

 

먼저 1번, 부모노드 확인입니다.

입력을 받으면서 자식으로 등록되는 노드(v)들을 Set을 이용하여 저장했고, 만약에 Set에 있는 값을 다시 넣게 된다면 자식으로 등록이 두번 됩니다. 즉 부모노드가 2개이상이 된다는 뜻입니다. => not tree

 

2번, 루트노드 확인입니다.

입력으로 주어지는 모든 부모노드(u)를 Set을 이용하여 저장했고, 만약에 Set에 있는 원소 중에 자식으로 등록되어있지 않으면 루트노드입니다.

만약 이러한 노드가 없거나 2개 이상이면 not tree입니다.

 

3번, 사이클 확인입니다.

map을 이용하여 Key는 부모노드(u), Value는 자식노드들(v)을 Integer, ArrayList<Integer>로 구현하였습니다.

사이클 확인은 dfs로 순회하여 next가 이미 방문한 노드인지 확인하였고, 이미 방문한 노드면 사이클이 있다는 말이기 때문에 not tree입니다.

 

3번의 확인이 끝나고 셋 다 아니라면 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
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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
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 Map<Integer, ArrayList<Integer>> m = new HashMap<>();
    static Set<Integer> findRoot = new HashSet<>();
    static Set<Integer> child = new HashSet<>();
    static Set<Integer> visit = new HashSet<>();
    static boolean tworoot, twoparents, cycle;
    static int u, v, root;
 
    static void dfs(int x) {
        visit.add(x);
 
        ArrayList<Integer> graph = m.get(x);
        if (graph == null)
            return;
 
        for (int i = 0; i < graph.size(); i++) {
            int next = graph.get(i);
 
            if (visit.contains(next)) {
                cycle = true;
                return;
            }
 
            dfs(next);
            if (cycle)
                return;
        }
    }
 
    static void rootFinding() {
        Iterator<Integer> iter = findRoot.iterator();
        while (iter.hasNext()) {
            int x = iter.next();
 
            if (!child.contains(x)) {
                if (root != 0) {
                    tworoot = true;
                    return;
                }
                root = x;
            }
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        while (true) {
            while (!st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
 
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
            if (u == 0 || u == -1)
                return;
 
            if (m.containsKey(u)) {
                m.get(u).add(v);
            } else {
                ArrayList<Integer> tmp = new ArrayList<>();
                tmp.add(v);
                m.put(u, tmp);
            }
            if (child.contains(v))
                twoparents = true;
            else
                child.add(v);
 
            findRoot.add(u);
        }
    }
 
    static void clear() {
        m.clear();
        findRoot.clear();
        child.clear();
        visit.clear();
        twoparents = false;
        tworoot = false;
        cycle = false;
        root = 0;
    }
 
    public static void main(String[] args) throws Exception {
        for (int T = 1;; T++) {
            input();
            if (u == -1)
                break;
 
            sb.append("Case " + T + " is ");
            if (child.isEmpty()) {
                sb.append("a tree.\n");
                continue;
            }
            if (twoparents) {
                sb.append("not a tree.\n");
                clear();
                continue;
            }
 
            rootFinding();
            if (root == 0 || tworoot) {
                sb.append("not a tree.\n");
                clear();
                continue;
            }
 
            dfs(root);
            if (cycle)
                sb.append("not a tree.\n");
            else
                sb.append("a tree.\n");
 
            clear();
        }
 
        System.out.println(sb.toString());
    }
}
cs

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

boj 1935 후위 표기식2  (0) 2021.02.05
boj 2493 탑  (0) 2021.02.04
boj 3190 뱀  (0) 2021.02.02
boj 2346 풍선 터뜨리기  (0) 2021.02.02
boj 5397 키로거  (0) 2021.02.02

www.acmicpc.net/problem/3190

 

3190번: 뱀

 'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임

www.acmicpc.net

입력으로 보드의 크기와 사과의 갯수, 좌표, 방향 회전 정보가 주어집니다.

여기서 좌표는 (1, 1) ~ (N, N)으로 주어지기 때문에 주어지는 크기에 맞게 접근을 해야합니다.

(그거때문에 런타임에러가 떴었습니다... 문제좀 제대로 읽어봐야하는데..)

 

저는 뱀의 위치를 덱으로 구현하여 덱의 맨 앞에는 뱀의 머리, 맨 뒤에는 뱀의 꼬리로 두었습니다.

그리고 뱀의 방향전환 정보가 최대 10000개라서 char배열을 이용하여 하였습니다.

 

뱀을 움직일 때는

1. 뱀이 움직인다. (움직인 곳으로 push)

2. 다음 칸이 사과면 꼬리가 위치한 칸을 그대로 둔다. (길이 +1)

3. 다음 칸이 사과가 아닌 빈칸이면 꼬리가 위치한 칸을 비운다. (길이 그대로)

4. 뱀을 움직이고 해당 시간에 회전명령이 있으면 회전한다.

5. 다음 칸이 뱀이 있는 위치이거나 맵 밖이면 게임이 끝난다. (T 출력)

위의 규칙대로 움직여주시면 됩니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static char ch[] = new char[10001];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int list[][];
    static Deque<int[]> dq = new ArrayDeque<>();
    static int N, K, L;
 
    static void func() {
        int idx = 0;
        dq.addLast(new int[] { 11 });
        list[1][1= 1;
        for (int T = 1;; T++) {
            int x = dq.peekFirst()[0];
            int y = dq.peekFirst()[1];
 
            int nx = x + direct[idx][0];
            int ny = y + direct[idx][1];
            if (nx <= 0 || ny <= 0 || nx > N || ny > N) {
                System.out.println(T);
                return;
            }
 
            if (list[nx][ny] == 2) {
                dq.addFirst(new int[] { nx, ny });
            } else if (list[nx][ny] == 0) {
                dq.addFirst(new int[] { nx, ny });
                list[dq.peekLast()[0]][dq.peekLast()[1]] = 0;
                dq.removeLast();
            } else {
                System.out.println(T);
                return;
            }
 
            if (ch[T] == 'L')
                idx = (idx + 3) % 4;
            else if (ch[T] == 'D')
                idx = (idx + 1) % 4;
 
            list[nx][ny] = 1;
        }
    }
 
    static void input() throws Exception {
        int x, y;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N + 1][N + 1];
 
        st = new StringTokenizer(br.readLine());
        K = Integer.parseInt(st.nextToken());
        while (K-- > 0) {
            st = new StringTokenizer(br.readLine());
            x = Integer.parseInt(st.nextToken());
            y = Integer.parseInt(st.nextToken());
 
            list[x][y] = 2;
        }
 
        st = new StringTokenizer(br.readLine());
        L = Integer.parseInt(st.nextToken());
        while (L-- > 0) {
            st = new StringTokenizer(br.readLine());
            x = Integer.parseInt(st.nextToken());
            char c = st.nextToken().charAt(0);
            ch[x] = c;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 2493 탑  (0) 2021.02.04
boj 6416 트리인가?  (0) 2021.02.04
boj 2346 풍선 터뜨리기  (0) 2021.02.02
boj 5397 키로거  (0) 2021.02.02
boj 10866 덱  (0) 2021.02.02

www.acmicpc.net/problem/2346

 

2346번: 풍선 터뜨리기

첫째 줄에 자연수 N(1≤N≤1,000)이 주어진다. 다음 줄에는 차례로 각 풍선 안의 종이에 적혀 있는 수가 주어진다. 편의상 0은 적혀있지 않다고 가정하자.

www.acmicpc.net

list의 첫번째 풍선을 터뜨리고 안에 적혀있는 수에 맞게 이동하여 다음 풍선을 터뜨리고, 최종적으로 풍선을 터뜨리는 순서를 구하는 문제입니다.

 

저는 덱을 이용하였습니다. 풍선을 터뜨릴 위치는 무조건 덱의 맨 앞입니다.

그러면 다음 위치를 찾아서 맨 앞으로 가져다 놓아야합니다.

 

풍선에 적혀있는 수가 양수면 오른쪽으로 이동하는 것인데

덱의 맨 앞의 숫자를 맨 뒤로 보내는 것으로 해결할 수 있습니다.

하지만 양수가 적혀있는 풍선을 터뜨리면 이미 한칸은 오른쪽으로 이동한 것이기 때문에 숫자-1만큼만 이동시킵니다.

 

풍선에 적혀있는 수가 음수면 왼쪽으로 이동합니다.

덱의 맨 뒤의 숫자를 맨 앞으로 보내는 것으로 해결할 수 있습니다.

 

마지막 풍선까지 터뜨리고 덱이 비어있으면 break를 해주고 답을 출력합니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
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 Deque<int[]> dq = new ArrayDeque<>();
    static int N;
 
    static void func() {
        for (int i = 0; i < N; i++) {
            int next = dq.peekFirst()[0];
            sb.append(dq.peekFirst()[1+ " ");
            dq.removeFirst();
 
            if (dq.isEmpty())
                break;
            
            if (next > 0) {
                next--;
                while (next-- > 0) {
                    dq.addLast(dq.peekFirst());
                    dq.removeFirst();
                }
            } else {
                while (next++ < 0) {
                    dq.addFirst(dq.peekLast());
                    dq.removeLast();
                }
            }
        }
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= N; i++) {
            dq.addLast(new int[] { Integer.parseInt(st.nextToken()), i });
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 6416 트리인가?  (0) 2021.02.04
boj 3190 뱀  (0) 2021.02.02
boj 5397 키로거  (0) 2021.02.02
boj 10866 덱  (0) 2021.02.02
boj 11000 강의실 배정  (0) 2021.02.01

www.acmicpc.net/problem/5397

 

5397번: 키로거

첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한줄로 이루어져 있고, 강산이가 입력한 순서대로 길이가 L인 문자열이 주어진다. (1 ≤ L의 길이 ≤ 1,000,000) 강산이가 백스페이

www.acmicpc.net

두 개의 덱을 이용하여 해결할 수 있습니다.

덱을 두 개 사용한 이유는 커서의 위치를 조정해주기 위함입니다.

저는 커서 좌, 우를 나누는 left와 right 덱을 선언하여 커서는 무조건 left를 가리키게 유지하였습니다.

 

우선 입력으로 '<', '>', '-' 그리고 나머지 문자가 주어집니다.

 

<이 주어지면 left에서 가장 뒤에있는 문자를 right 앞으로 push합니다. (left가 비어있으면 패스)

>이 주어지면 right에서 가장 앞에있는 문자를 left 뒤로 push합니다. (right가 비어있으면 패스)

-이 주어지면 left에서 가장 뒤에있는 문자를 pop합니다. (left가 비어있으면 패스)

나머지 문자가 주어지면 커서를 left로 유지해야하기 때문에 left 뒤로 push합니다.

 

이 과정이 끝나면 right에 있는 문자들을 앞에서부터 순서대로 left의 뒤로 차례대로 push하여 출력합니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
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 Deque<Character> left, right;
    static char ch[];
 
    static void print() {
        while(!left.isEmpty()) {
            sb.append(left.peekFirst());
            left.removeFirst();
        }
        
        sb.append("\n");
    }
    
    static void func() {
        for (int i = 0; i < ch.length; i++) {
            if (ch[i] == '<') {
                if (left.isEmpty())
                    continue;
                right.addFirst(left.peekLast());
                left.removeLast();
            } else if (ch[i] == '>') {
                if (right.isEmpty())
                    continue;
                left.addLast(right.peekFirst());
                right.removeFirst();
            } else if (ch[i] == '-') {
                if (left.isEmpty())
                    continue;
                left.removeLast();
            } else
                left.addLast(ch[i]);
        }
        
        while(!right.isEmpty()) {
            left.addLast(right.peekFirst());
            right.removeFirst();
        }
    }
 
    static void input() throws Exception {
        left = new ArrayDeque<>();
        right = new ArrayDeque<>();
 
        st = new StringTokenizer(br.readLine());
        ch = st.nextToken().toCharArray();
    }
 
    public static void main(String[] args) throws Exception {
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            input();
            func();
            print();
        }
        System.out.println(sb.toString());
    }
}
cs

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

boj 3190 뱀  (0) 2021.02.02
boj 2346 풍선 터뜨리기  (0) 2021.02.02
boj 10866 덱  (0) 2021.02.02
boj 11000 강의실 배정  (0) 2021.02.01
boj 1966 프린터 큐  (0) 2021.02.01

+ Recent posts