문제

 

절댓값 힙은 다음과 같은 연산을 지원하는 자료구조이다.

  1. 배열에 정수 x (x ≠ 0)를 넣는다.
  2. 배열에서 절댓값이 가장 작은 값을 출력하고, 그 값을 배열에서 제거한다. 절댓값이 가장 작은 값이 여러개일 때는, 가장 작은 수를 출력하고, 그 값을 배열에서 제거한다.

첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 

 

만약 x가 0이 아니라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이라면 배열에서 절댓값이 가장 작은 값을 출력하고 그 값을 배열에서 제거하는 경우이다. (정수는 -231보다 크고, 231보다 작다.) 

만약 배열이 비어 있는 경우인데 절댓값이 가장 작은 값을 출력하라고 한 경우에는 0을 출력한다.

 


PriorityQueue를 사용하면 쉽게 풀릴 것 같은데 절댓값이 같은 경우 음수를 반환해야 하기 때문에 이부분만 따로 if문으로 조건 처리를 해주었다.

 

 

    PriorityQueue<Integer> queue = new PriorityQueue<>(Main::compareToAbs);

    int N = Integer.parseInt(br.readLine());
    for (int i = 0; i < N; i++) {
        int value = Integer.parseInt(br.readLine());

        if (value != 0) {
            queue.add(value);
            continue;
        }

        if (queue.isEmpty()) {
            sb.append("0").append("\n");
            continue;
        }

        sb.append(queue.poll()).append("\n");
    }

    System.out.println(sb);
}

private static int compareToAbs(Integer n1, Integer n2) {
    int a1 = Math.abs(n1);
    int a2 = Math.abs(n2);

    if (a1 == a2) {
        if (n1 < n2) {
            return -1;
        }
        return 1;
    }

    return a1 - a2;
}

'코딩테스트' 카테고리의 다른 글

[백준, 2164] 카드2  (0) 2023.03.05
[백준, 17298] 오큰수  (0) 2023.03.05
[백준, 1874] 스택 수열  (0) 2023.03.05
[백준, 12891] DNA 비밀번호  (0) 2023.03.05
[백준, 1940] 주몽의 명령  (0) 2023.03.04

문제

 

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

 

다음 동작을 카드가 한 장 남을 때까지 반복

-> 제일 위에 있는 카드를 바닥에 버린다. 그 다음, 제일 위에 있는 카드를 제일 아래에 있는 카드 밑으로 옮긴다.

 

 


입력 예시가 6이면 카드는 위에서부터 1,2,3,4,5,6 으로 쌓여있는 상태이다.

1을 버리고 2를 제일 밑으로 보내는 식으로 반복하면

 

1) 3,4,5,6,2

2) 5,6,2,4

3) 2,4,6

4) 6,4

 

마지막에 6을 버리면 정답은 4가 된다.

 

제일 위에 숫자를 버리고 제일 밑에 숫자를 추가하는 식의 동작이기 때문에 Deque를 사용하면 될 것 같다.

처음에 Deque가 떠올랐는데 생각해보니 그냥 Queue를 사용해도 poll하고 다시 넣으면 제일 뒤로 가기 때문에 더 나은 것 같다.

 

int N = Integer.parseInt(br.readLine());

Deque<Integer> deque = new LinkedList<>();

for (int i = 1; i <= N; i++) {
    deque.addFirst(i);
}

while (deque.size() > 1) {
    deque.removeLast();
    deque.addFirst(deque.removeLast());
}

System.out.println(deque.peek());

 

'코딩테스트' 카테고리의 다른 글

[백준, 11286] 절댓값 힙  (0) 2023.03.05
[백준, 17298] 오큰수  (0) 2023.03.05
[백준, 1874] 스택 수열  (0) 2023.03.05
[백준, 12891] DNA 비밀번호  (0) 2023.03.05
[백준, 1940] 주몽의 명령  (0) 2023.03.04

문제

 

크기가 N인 수열 A = A1, A2, ..., AN이 있다.

Ai의 오큰수는 오른쪽에 있으면서 Ai보다 큰 수 중에서 가장 왼쪽에 있는 수 (그러한 수가 없는 경우에 오큰수는 -1)

 

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다. 이 때, 차례대로 오큰수를 출력

 


 

오른쪽에 있으면서 가장 왼쪽에 있는 수는 자기보다 큰 수가 나오면 바로 찾아지는데 단순하게 계산하면 for문 2개를 돌리게 된다.

더 나은 방법을 생각해봤는데 떠오르지 않아 찾아보니 스택에 값이 아닌 인덱스를 활용해서 푸는 방법이 있었다.

 

stack에는 인덱스를 push 하는데 배열의 다음 값과 stack에서 peek을 한 인덱스에 해당하는 값을 비교해서 다음 값이 작을 경우에 해당 값의 인덱스를 stack에 push 한다. 그러다가 stack의 인덱스에 해당하는 값보다 큰 값을 만나면 오큰수로 체크하는 식으로 계산하면 된다. 처음에 오큰수를 기록하는 answer 배열을 -1로 초기화하기 때문에 오큰수가 없는 경우는 따로 체크할 필요가 없다.

 

int N = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());

Stack<Integer> stack = new Stack<>();
int[] arr = new int[N];
int[] answer = new int[N];

for (int i = 0; i < N; i++) {
    arr[i] = Integer.parseInt(st.nextToken());
}

Arrays.fill(answer, -1);

stack.push(0);
for (int i = 1; i < arr.length; i++) {
    while (!stack.isEmpty() && arr[stack.peek()] < arr[i]) {
        answer[stack.pop()] = arr[i];
    }
    stack.push(i);
}

for (int num : answer) {
    sb.append(num).append(" ");
}

System.out.println(sb);

 

'코딩테스트' 카테고리의 다른 글

[백준, 11286] 절댓값 힙  (0) 2023.03.05
[백준, 2164] 카드2  (0) 2023.03.05
[백준, 1874] 스택 수열  (0) 2023.03.05
[백준, 12891] DNA 비밀번호  (0) 2023.03.05
[백준, 1940] 주몽의 명령  (0) 2023.03.04

문제

 

1부터 n까지의 수를 스택에 넣었다가 뽑아 늘어놓음으로써, 하나의 수열을 만들 수 있다.

이때, 스택에 push하는 순서는 반드시 오름차순을 지키도록 한다고 하자.

임의의 수열이 주어졌을 때 스택을 이용해 그 수열을 만들 수 있는지 없는지, 있다면 어떤 순서로 push와 pop 연산을 수행해야 하는지를 알아낼 수 있다. 이를 계산하는 프로그램을 작성하시오

 

문제의 예시를 보면 "4 3 6 8 7 5 2 1" 가 주어지면 stack을 사용해서 해당 수열을 만들 수 있는지 구하는 것이다.

 

stack에는 오름차순으로 push를 해야하는 규칙이 있기 때문에 1, 2, 3, 4.. 순서로 push를 하고 4가 push 되었을때 pop을 2번 하면 4, 3이 나오게 되어서 문제의 예시대로 4, 3을 만들 수 있다.

 

먼저 입력을 받아서 기존의 배열과 오름차순으로 정렬이 된 배열을 만든다.

그리고 정렬이 된 배열에서 하나씩 push를 하다가 기존의 배열 순서에 맞는 숫자가 나오면 pop을 하는 식으로 구현하면 될 것 같다.

 

int N = Integer.parseInt(br.readLine());
int[] arr = new int[N];
int[] sortedArr = new int[N];
Stack<Integer> stack = new Stack<>();

for (int i = 0; i < N; i++) {
    int value = Integer.parseInt(br.readLine());
    arr[i] = value;
    sortedArr[i] = value;
}

Arrays.sort(sortedArr);

int idx = 0;
for (int num : sortedArr) {
    sb.append("+").append("\n");
    stack.push(num);
    while (!stack.isEmpty() && stack.peek() == arr[idx]) {
        sb.append("-").append("\n");
        stack.pop();
        ++idx;
    }
}

if (!stack.isEmpty()) {
    System.out.println("NO");
    return;
}

System.out.println(sb);

 

 

'코딩테스트' 카테고리의 다른 글

[백준, 2164] 카드2  (0) 2023.03.05
[백준, 17298] 오큰수  (0) 2023.03.05
[백준, 12891] DNA 비밀번호  (0) 2023.03.05
[백준, 1940] 주몽의 명령  (0) 2023.03.04
[백준, 2018] 수들의 합  (0) 2023.03.04

+ Recent posts