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/2164

 

2164번: 카드2

N장의 카드가 있다. 각각의 카드는 차례로 1부터 N까지의 번호가 붙어 있으며, 1번 카드가 제일 위에, N번 카드가 제일 아래인 상태로 순서대로 카드가 놓여 있다. 이제 다음과 같은 동작을 카드가

www.acmicpc.net

큐에 1부터 N까지 순서대로 push가 된 상태로 있습니다.

 

여기서 다음과 같은 동작을 카드가 하나 남을때까지 반복합니다.

1. 큐의 가장 위에있는 숫자를 버린다.

2. 큐의 가장 위에있는 숫자를 큐의 맨 뒤로 보내고 삭제한다.

 

큐의 크기가 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
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 Queue<Integer> q = new LinkedList<>();
    static int N;
 
    static void func() {
        while (true) {
            if (q.size() == 1)
                break;
            
            q.remove();
            q.add(q.peek());
            q.remove();
        }
        
        System.out.println(q.peek());
    }
 
    static void init() {
        for (int i = 1; i <= N; i++) {
            q.add(i);
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
    }
 
    public static void main(String[] args) throws Exception {
        input();
        init();
        func();
    }
}
cs

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

boj 11000 강의실 배정  (0) 2021.02.01
boj 1966 프린터 큐  (0) 2021.02.01
boj 10845 큐  (0) 2021.02.01
boj 1655 가운데를 말해요  (0) 2021.02.01
boj 11279 최대 힙  (0) 2021.01.31

www.acmicpc.net/problem/10845

 

10845번: 큐

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지

www.acmicpc.net

큐의 여러가지 기능을 사용해 볼 수 있는 간단한 문제입니다.

 

입력으로 6개의 명령이 주어집니다.

push X : 정수 X를 push

pop : q.peek()를 출력 후 pop, 만약 큐가 비어있으면 -1 출력

size : 큐의 크기를 출력

empty : 큐가 비어있으면 1, 아니면 0 출력

front : q.peek()를 출력, 만약 큐가 비어있으면 -1 출력

back : 큐에 가장 최근에 push된 정수 출력, 만약 큐가 비어있으면 -1 출력

 

큐가 비어있으면 -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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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, last;
 
    static void push(int x) {
        q.add(x);
    }
 
    static void pop() {
        if (q.isEmpty()) {
            sb.append("-1\n");
            return;
        }
 
        sb.append(q.peek() + "\n");
        q.remove();
    }
 
    static void size() {
        sb.append(q.size() + "\n");
    }
 
    static void empty() {
        if (q.isEmpty())
            sb.append("1\n");
        else
            sb.append("0\n");
    }
 
    static void front() {
        if (q.isEmpty()) {
            sb.append("-1\n");
            return;
        }
 
        sb.append(q.peek() + "\n");
    }
 
    static void back() {
        if (q.isEmpty()) {
            sb.append("-1\n");
            return;
        }
 
        sb.append(last + "\n");
    }
 
    static void input() throws Exception {
        String type;
        int x;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        while (N-- > 0) {
            st = new StringTokenizer(br.readLine());
            type = st.nextToken();
 
            if ("push".equals(type)) {
                x = Integer.parseInt(st.nextToken());
                push(x);
                last = x;
            } else if ("pop".equals(type))
                pop();
            else if ("size".equals(type))
                size();
            else if ("empty".equals(type))
                empty();
            else if ("front".equals(type))
                front();
            else
                back();
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        System.out.println(sb.toString());
    }
}
cs

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

boj 1966 프린터 큐  (0) 2021.02.01
boj 2164 카드2  (0) 2021.02.01
boj 1655 가운데를 말해요  (0) 2021.02.01
boj 11279 최대 힙  (0) 2021.01.31
boj 1927 최소 힙  (0) 2021.01.31

www.acmicpc.net/problem/1655

 

1655번: 가운데를 말해요

첫째 줄에는 수빈이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 수빈이가 외치는 정수가 차례대로 주어진다. 정수는 -1

www.acmicpc.net

 

수빈이가 동생에게 숫자를 하나씩 부를 때마다 동생이 처음에 말한 수부터 현재 말한 수까지의 중간 값을 출력해야합니다.

 

이 문제는 우선순위 큐로 해결할 수 있습니다.

저는 우선순위 큐 2개(최대 힙, 최소 힙 각각 1개)를 사용하였습니다.

최대 힙에는 작은값들, 최소 힙에는 큰 값들을 저장합니다. 그리고 출력은 최대힙에서 가장 작은 수를 출력합니다.

 

출력을 최대 힙으로 사용하기 때문에 최대 힙의 크기를 더 크게 유지시킵니다.

하지만 중간 값을 구해야하기 때문에 최대 힙과 최소 힙의 크기를 같게 하거나 최대 힙의 크기가 1만큼 더 커야합니다.

 

우선 최대 힙이 비어있으면 최대 힙에 저장합니다.

그리고 최대 힙의 크기가 최소 힙과 같으면 최대 힙에 add

최소 힙의 크기가 더 작으면 최소 힙에 add를 해줍니다.

 

이 과정 이후에 최소 힙의 가장 작은 값이 최대 힙의 가장 큰 값보다 작으면 두 수를 교환합니다.

 

마지막에는 최대 힙에서 가장 큰 수를 출력하면 됩니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
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 int list[];
    static int N;
 
    static void func() {
        PriorityQueue<Integer> maxq = new PriorityQueue<>();
        PriorityQueue<Integer> minq = new PriorityQueue<>();
 
        for (int i = 0; i < N; i++) {
            int x = list[i];
 
            if (maxq.isEmpty()) {
                maxq.add(-x);
                sb.append(-maxq.peek() + "\n");
                continue;
            }
 
            if (maxq.size() == minq.size())
                maxq.add(-x);
            else
                minq.add(x);
 
            if (-maxq.peek() > minq.peek()) {
                int a = -maxq.peek();
                int b = -minq.peek();
                maxq.remove();
                minq.remove();
 
                maxq.add(b);
                minq.add(a);
            }
 
            sb.append(-maxq.peek() + "\n");
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N];
 
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        System.out.println(sb.toString());
    }
}
cs

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

boj 2164 카드2  (0) 2021.02.01
boj 10845 큐  (0) 2021.02.01
boj 11279 최대 힙  (0) 2021.01.31
boj 1927 최소 힙  (0) 2021.01.31
boj 4889 안정적인 문자열  (0) 2021.01.26

+ Recent posts