고코딩
[백준 1966번] 프린터 큐 본문
문제
여러분도 알다시피 여러분의 프린터 기기는 여러분이 인쇄하고자 하는 문서를 인쇄 명령을 받은 ‘순서대로’, 즉 먼저 요청된 것을 먼저 인쇄한다. 여러 개의 문서가 쌓인다면 Queue 자료구조에 쌓여서 FIFO - First In First Out - 에 따라 인쇄가 되게 된다. 하지만 상근이는 새로운 프린터기 내부 소프트웨어를 개발하였는데, 이 프린터기는 다음과 같은 조건에 따라 인쇄를 하게 된다.
- 현재 Queue의 가장 앞에 있는 문서의 ‘중요도’를 확인한다.
- 나머지 문서들 중 현재 문서보다 중요도가 높은 문서가 하나라도 있다면, 이 문서를 인쇄하지 않고 Queue의 가장 뒤에 재배치 한다. 그렇지 않다면 바로 인쇄를 한다.
예를 들어 Queue에 4개의 문서(A B C D)가 있고, 중요도가 2 1 4 3 라면 C를 인쇄하고, 다음으로 D를 인쇄하고 A, B를 인쇄하게 된다.
여러분이 할 일은, 현재 Queue에 있는 문서의 수와 중요도가 주어졌을 때, 어떤 한 문서가 몇 번째로 인쇄되는지 알아내는 것이다. 예를 들어 위의 예에서 C문서는 1번째로, A문서는 3번째로 인쇄되게 된다.
입력
첫 줄에 테스트케이스의 수가 주어진다. 각 테스트케이스는 두 줄로 이루어져 있다.
테스트케이스의 첫 번째 줄에는 문서의 개수 N(1 ≤ N ≤ 100)과, 몇 번째로 인쇄되었는지 궁금한 문서가 현재 Queue에서 몇 번째에 놓여 있는지를 나타내는 정수 M(0 ≤ M < N)이 주어진다. 이때 맨 왼쪽은 0번째라고 하자. 두 번째 줄에는 N개 문서의 중요도가 차례대로 주어진다. 중요도는 1 이상 9 이하의 정수이고, 중요도가 같은 문서가 여러 개 있을 수도 있다.
출력
각 테스트 케이스에 대해 문서가 몇 번째로 인쇄되는지 출력한다.
정답
지금 까지 풀었더 문제 중에 너무 난해했다. 중요도를 큐에 넣어서 맨 앞의 값을 뒤에 값들과 비교해 뒤에 큰 값이 있다면 맨 앞의 값을 큐의 맨 뒤로 보내고 맨 앞의 값을 없앤우 위의 과정을 반복한다.
만약 맨 앞의 큐보다 큰 값이 없을때 지금 맨 앞의 큐가 몇번째로 인쇄되는지 알고싶은 문서라면 출력 순서를 출력하면 된다는 것은 보고 바로 알았다. 다만 이것을 코딩으로 규현할때 큐를 반드시 사용해서 써야 한다는 생각에 너무 복잡하게 풀었고 비교를 위한 여러가지 변수들 때문에 코드도 난잡해져서 멘탈이 살짝 나갔다. 약 하루 정도 고민하면서 풀다가 혹시 다른 사람은 어떻게 효율적으로 풀었는지 찾아봤는데 내가 처음에 생각한 그 방식대로 풀었다. 다만 직접 큐를 사용하지 않고 LinkedList
를 이용해 큐의 성질만을 가져다 사용했다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int testcase = Integer.parseInt(br.readLine());
for(int i=0; i<testcase ; i++) {
String [] NM = br.readLine().split(" ");
int N = Integer.parseInt(NM[0]); //문서의 갯수 1<= N <= 100
int M = Integer.parseInt(NM[1]); //Queue에서 문서의 위치가 궁금한 정수
StringTokenizer priorities = new StringTokenizer(br.readLine(), " ");// 중요도
LinkedList<Node> queue = new LinkedList<Node>();
int index = 0;
while(priorities.hasMoreTokens()) {
if(index == M) {
queue.add(new Node(Integer.parseInt(priorities.nextToken()),true)); //출력순서 알고싶은 문서는 true
}else {
queue.add(new Node(Integer.parseInt(priorities.nextToken()),false)); // 그 외 문서는 false로 지정
}
index++;
}
int printOrder = 1; //출력순서
//queue가 빌때까지 확인
while(!queue.isEmpty()) {
//맨 앞의 값을 확인
Node firstNode = queue.get(0);
boolean check = true; //우선순위를 확인하는 변수
//맨 앞의 값 보다 큰 값중 가장 큰 값 찾기
for(int j=0;j<queue.size();j++) {
//값이 크면
if(firstNode.getData() < queue.get(j).getData()) {
check = false;
break;
}
}
//현재 맨 앞보다 큰 값이 있다면
if(check == false) {
queue.add(firstNode); //맨 앞의 값 뒤로 보내고
queue.remove(0); //맨 앞의 값 삭제
}else {
if(firstNode.getM() == true) { //지금 출력하는 문서가 순서를 알고싶은 그 문서면 출력
System.out.println(printOrder);
}else { //아니면 출력 순서만 +1
printOrder++;
}
queue.remove(0); //맨 앞의 문서는 무조건 출력이므로 제거
}
}
}
br.close();
bw.flush();
bw.close();
}
static class Node{
int data;
boolean M;
public Node(int data,boolean M) {
this.data = data;
this.M = M;
}
public int getData() {
return this.data;
}
public boolean getM() {
return this.M;
}
}
}
'코딩테스트' 카테고리의 다른 글
[백준 10773번] 제로 (0) | 2021.01.04 |
---|---|
[백준 10866번] 덱 (0) | 2021.01.04 |
[백준 10799번] 쇠막대기 (0) | 2020.12.31 |
[백준 1874번] 스택 수열 (0) | 2020.12.31 |
[백준 1158번] 요세푸스 문제 (0) | 2020.12.31 |