백준 1966번: 프린터 큐
by Jm Park
문제
여러분도 알다시피 여러분의 프린터 기기는 여러분이 인쇄하고자 하는 문서를 인쇄 명령을 받은 ‘순서대로’, 즉 먼저 요청된 것을 먼저 인쇄한다. 여러 개의 문서가 쌓인다면 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번째로 인쇄되게 된다.
입력
첫 줄에 test case의 수가 주어진다. 각 test case에 대해서 문서의 수 N(100이하)와 몇 번째로 인쇄되었는지 궁금한 문서가 현재 Queue의 어떤 위치에 있는지를 알려주는 M(0이상 N미만)이 주어진다. 다음줄에 N개 문서의 중요도가 주어지는데, 중요도는 적절한 범위의 int형으로 주어진다. 중요도가 같은 문서가 여러 개 있을 수도 있다. 위의 예는 N=4, M=0(A문서가 궁금하다면), 중요도는 2 1 4 3이 된다.
출력
각 test case에 대해 문서가 몇 번째로 인쇄되는지 출력한다.
예제 입력/출력
입력 | 출력 |
---|---|
3 1 0 5 4 2 1 2 3 4 6 0 1 1 9 1 1 1 |
1 2 5 |
코드
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
int main() {
int t, m, n;
scanf("%d", &t);
while (t--) {
vector<int> que;
vector<int> priority_que;
int cnt = 1;
scanf("%d %d", &n, &m);
que.resize(n);
for (int i = 0; i < n; i++) {
scanf("%d", &que[i]);
priority_que.push_back(que[i]);
}
// 우선순위대로 내림차순 정렬
sort(priority_que.begin(), priority_que.end(), greater<int>());
while (true) {
// 우선순위가 낮은 문서가 앞에 있는 경우 뒤로 보내줌
if (priority_que.front() > que.front()) {
// 해당 문서가 입력받은 "원하는 문서"일 경우, 인덱스를 문서의 맨 마지막으로 바꿔줌
// 해당 문서가 원하는 문서가 아닐경우, "원하는 문서"의 인덱스를 한칸 앞당겨줌
m = m != 0 ? m - 1 : n - 1;
que.push_back(que.front());
que.erase(que.begin());
}
// 우선순위에 맞는 문서가 앞에 있는 경우 출력
else if (priority_que.front() == que.front()) {
// 해당 문서가 원하는 문서가 아닐 경우, "원하는 문서"의 인덱스를 한칸 앞당겨줌
if (m != 0) {
m--;
n--; // 출력으로 인해 남아있는 문서의 갯수가 줄어듬
priority_que.erase(priority_que.begin());
que.erase(que.begin());
cnt++;
}
// 해당 문서가 입력받은 "원하는 문서"일 경우 그대로 탈출
else {
printf("%d\n", cnt);
break;
}
}
}
}
return 0;
}
풀이
위 코드의 알고리즘은 아래와 같다.
- 입력 받은 문서를 que와 priority_que에 저장한다.
- priority_que는 내림차순으로 정렬한다.
- priority_que와 que의 맨 앞에 위치해 있는 문서의 우선순위를 비교한다.
- que의 우선순위가 낮은 경우 해당 문서는 맨 뒤로 보낸다.
- 그 문서가 “m번째 문서(출력순서를 요구하는 문서)”에 해당되는 경우, m값을 que 가장 마지막값으로 바꾼다.
- 그렇지 않다면, “m번째 문서”의 m값을 하나 줄인다.(한칸 앞당겨짐)
- que의 우선순위가 priority_que의 우선순위와 동일한 경우 출력한다.
- 그 문서가 “m번째 문서”에 해당되는 경우, 그대로 출력순서를 출력한다.
- 그렇지 않다면, 출력순서 cnt를 증가시켜주고 m값은 하나 줄인다. (한칸 앞당겨짐) 3-5번을 반복한다.
문제 풀이가 그렇게 깔끔하진 않지만, 시간내에 풀린다.
코드가 지저분해 보여서 아쉽다.
Subscribe via RSS