출처 : https://www.acmicpc.net/problem/1966
프린터 큐 성공 풀이
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞은 사람 | 정답 비율 |
---|---|---|---|---|---|
2 초 | 128 MB | 4664 | 2215 | 1859 | 51.942% |
문제
여러분도 알다시피 여러분의 프린터 기기는 여러분이 인쇄하고자 하는 문서를 인쇄 명령을 받은 ‘순서대로’, 즉 먼저 요청된 것을 먼저 인쇄한다. 여러 개의 문서가 쌓인다면 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
힌트
>> 풀이 방법
나는 우선순위 큐를 하지 못한 상태에서 풀이를 진행했다.
먼저 구조체를 생성하여 문서 번호와 우선순위를 넣어주었다.
그리고 나서 위와 같이 구조체를 저장하는 배열과 queue를 하나씩 생성한다.
그리고 매 라운드마다 rank_arr 에서 최대의 값을 탐색하여 찾아낸다.
그리고 rank_queue 에서 최대값이 전부 다 나올 때 까지, 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 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 | #include <iostream> #include <queue> #include <vector> using namespace std; typedef struct NODE { int docu_num; int rank; }NODE; queue<NODE*> rank_queue; int docu_num, find_docu_num, print_order = 0, isFind = 0, max_num ; NODE** rank_arr; vector<int> answer; int findMax() { max_num = 0; int max = rank_arr[0]->rank; // 최대값 찾기 for (int j = 1; j < docu_num; j++) { if (max < rank_arr[j]->rank) max = rank_arr[j]->rank; } // max 를 -1으로 메꿔버리기 for (int j = 0; j < docu_num; j++) { if (max == rank_arr[j]->rank) { rank_arr[j]->rank = -1; max_num++; } } return max; } int main(){ int test_case; cin >> test_case; for (int i = 0; i < test_case; i++) { print_order = 0; cin >> docu_num >> find_docu_num; rank_arr = (NODE**)malloc(sizeof(NODE*)*docu_num); // 큐 초기화 while (rank_queue.size()) rank_queue.pop(); for (int j = 0; j < docu_num; j++){ rank_arr[j] = (NODE*)malloc(sizeof(NODE)*docu_num); rank_arr[j]->docu_num = j; cin >> rank_arr[j]->rank; NODE* sub_node = (NODE*)malloc(sizeof(NODE)*docu_num); sub_node->docu_num = j; sub_node->rank = rank_arr[j]->rank; rank_queue.push(sub_node); } isFind = 0; while (!isFind) { // 최대값 찾기 int sub_max = findMax(); // 최대값인 놈들을 출력해준다. int sub_queue_size = rank_queue.size(); // 큐 1바퀴 for (int j = 0; j < sub_queue_size; j++) { // 받아서 비교하기 NODE* sub_node = rank_queue.front(); // 최대 값이 뒤에 없으면 if (max_num == 0) { // 만약 현재 노드가 값이 최대값과 같고, 목적 노드라면 if (sub_node->docu_num == find_docu_num && sub_node->rank == max_num) { print_order++; isFind = 1; break; } // 아니면 else { break; } } // 제거 rank_queue.pop(); // 만약 최대값과 랭크가 같으면 if (sub_node->rank == sub_max) { // 찾고자 하는 index가 맞는지 확인 // 맞으면 정답이다 !! if (sub_node->docu_num == find_docu_num) { print_order++; isFind = 1; break; } // 틀리면 else { print_order++; max_num--; } } else { rank_queue.push(sub_node); } } } answer.push_back(print_order); } for (int i = 0; i < answer.size(); i++) { cout << answer[i] << "\n"; } return 0; } | cs |
>> 더 짧은 풀이
우선순위 큐를 사용하여 어마어마하게 간단해졌다..
역시 짦은 풀이 참고는 필수인 듯 하다.
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 | #include<cstdio> #include<queue> #pragma warning(disable :4996) using namespace std; int main(void) { int t; scanf("%d", &t); for (int testcase = 0; testcase < t; testcase++) { int N, M,cnt = 0; queue <pair<int, int>> q; priority_queue <int> pq; scanf("%d %d",&N,&M); for (int i = 0; i < N; i++) { int a; scanf("%d", &a); q.push({i,a}); pq.push(a); } while (!q.empty()) { //현재 배열의 인덱스와 중요도 int nowidx = q.front().first; int nowval = q.front().second; q.pop(); if (pq.top() == nowval) { pq.pop(); cnt++; if (nowidx == M) { printf("%d\n", cnt); break; } } else { q.push({ nowidx,nowval }); } } } return 0; } |