출처: 프로그래머스
문제 설명
일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린터를 개발했습니다. 이 새롭게 개발한 프린터는 아래와 같은 방식으로 인쇄 작업을 수행합니다.
1. 인쇄 대기목록의 가장 앞에 있는 문서(J)를 대기목록에서 꺼냅니다. 2. 나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에 넣습니다. 3. 그렇지 않으면 J를 인쇄합니다.
예를 들어, 4개의 문서(A, B, C, D)가 순서대로 인쇄 대기목록에 있고 중요도가 2 1 3 2 라면 C D A B 순으로 인쇄하게 됩니다.
내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 알고 싶습니다. 위의 예에서 C는 1번째로, A는 3번째로 인쇄됩니다.
현재 대기목록에 있는 문서의 중요도가 순서대로 담긴 배열 priorities와 내가 인쇄를 요청한 문서가 현재 대기목록의 어떤 위치에 있는지를 알려주는 location이 매개변수로 주어질 때, 내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 return 하도록 solution 함수를 작성해주세요.
제한사항
- 현재 대기목록에는 1개 이상 100개 이하의 문서가 있습니다.
- 인쇄 작업의 중요도는 1~9로 표현하며 숫자가 클수록 중요하다는 뜻입니다.
- location은 0 이상 (현재 대기목록에 있는 작업 수 - 1) 이하의 값을 가지며 대기목록의 가장 앞에 있으면 0, 두 번째에 있으면 1로 표현합니다.
입출력 예
priorities | location | return
| [2, 1, 3, 2] | 2 | 1 |
| [1, 1, 9, 1, 1, 1] | 0 | 5 |
입출력 예 설명
예제 #1
문제에 나온 예와 같습니다.
예제 #2
6개의 문서(A, B, C, D, E, F)가 인쇄 대기목록에 있고 중요도가 1 1 9 1 1 1 이므로 C D E F A B 순으로 인쇄합니다.
풀이과정
1. 그냥 위에 설명한 인쇄작업대로 코드 작성하면 될 것 같다.
2. 맨 앞에 있는거 꺼냄
3. 꺼낸 거 제외하고 location에 있는게 몇번째에 출력되는지 확인
4. 대신 최대 (현재 대기목록에 있는 작업수 -1)만큼만 체크
-> 그냥 location만큼 체크하면 될듯.
cf) location 은 처음 주어진 인쇄목록의 1이 아닌 0부터 카운팅함
정답이 아닌 혼돈의 코드
import java.util.*;
class Solution {
public int solution(int[] priorities, int location) {
Queue<Integer> printQueue = new LinkedList<>();
for(int i =0;i<priorities.length;i++) {
printQueue.offer(priorities[i]);
// System.out.println("tmp : " + priorities[i]);
}
int cnt = 0 ;
while(cnt<priorities.length) {
if(printQueue.peek()==priorities[location] && cnt == priorities.length-1-location) {
break;
}
for(int i = 0;i<priorities.length;i++) {
if(priorities[i]>printQueue.peek())
{
printQueue.offer(printQueue.poll());
break;
}
}
cnt++;
System.out.println(printQueue.peek());
}
System.out.println(printQueue.peek());
System.out.println(cnt-1);
return cnt-1;
}
}
큐를 사용하는 건 알겠는데 같은 숫자이지만 다른 인쇄물일 경우를 어떻게 판단할지 기준을 세우지 못하였다...
map을 사용했으면 됬으려나 싶기도 한데 큐를 사용하여 푸는 답을 참고하였다.
내 생각대로 하려면 우선순위큐를 사용해야 했다...
핵심은
어차피 인쇄를 하기 위해서는
인쇄목록에 우선순위가 높은 것을 찾아야한다.
그 뒤부터 인쇄순위 카운트 가능
다시정리하면
결국엔 우선순위 내림차순으로 정렬될 것이고
정렬되고 난 후의 인쇄예정목록에서
기존에 주어진 로케이션과 배열이 어떤 것이었는지, 매칭하는 경우를 따지는 것임
참고하여 작성한 코드
package Test;
import java.util.*;
public class MainNew {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] priorities = { 1,1,9,1,1,1}; // 2,1,3,2
int location =0; // 2;
int[] number = { location, priorities[location] };
int answer = 0;
PriorityQueue<Integer> printQueue = new PriorityQueue<>(Collections.reverseOrder());
// 우선순위 숫자 내림차순 정렬로 담는다.
for (int i = 0; i < priorities.length; i++) {
System.out.println(priorities[i]);
printQueue.offer(priorities[i]);
}
System.out.println(printQueue);
int cnt = 0 ;
// 최대: 큐가 완전히 비어질 때까지 비교해줌
while (!printQueue.isEmpty()) {
for (int i = 0; i < priorities.length; i++) {
// 큐에 담긴 것이 인쇄목록에 있으면
if (printQueue.peek() == priorities[i]) {
System.out.println("peek = " + printQueue.peek());
// 큐에서 빼주고 출력횟수 카운트
System.out.println("i = " + i + " poll = " + printQueue.poll());
answer++;
System.out.println("answer = " + answer);
// 큐에 담긴 것이 인쇄목록에 있고, 그것이 찾는위치와 같으면 큐 비우고 끝내
// 주어진 로케이션과 주어진 배열과의 매칭이 되는지 파악하는 것이 중요
if (location == i) {
printQueue.clear();
break;
}
}
}
cnt++;
System.out.println("cnt = " + cnt);
System.out.println("cnt peek = " + printQueue.peek());
}
} // main
} // MainNew
memo
하ㅓ 너무 어렵다
그래도 해야지..
'머리맞대는이야기 > 프로그래머스 (JAVA)' 카테고리의 다른 글
| [해시] 베스트앨범 (0) | 2020.09.06 |
|---|---|
| [연습문제] 시저 암호 (0) | 2020.09.06 |
| [연습문제] 나누어 떨어지는 숫자 배열 (0) | 2020.09.01 |
| [연습문제] 최대공약수와 최소공배수 (0) | 2020.08.31 |
| [스택/큐] 다리를 지나는 트럭 (0) | 2020.08.30 |