Do Something

[프로그래머스][c++][스택/큐] 프린터(vector iter사용) 본문

프로그래머스

[프로그래머스][c++][스택/큐] 프린터(vector iter사용)

뭐라도해야겠다 2022. 1. 24. 03:30

 

문제 설명

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린터를 개발했습니다. 이 새롭게 개발한 프린터는 아래와 같은 방식으로 인쇄 작업을 수행합니다.

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로 표현합니다.
입출력 예prioritieslocationreturn
[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 순으로 인쇄합니다.


이번에도 최대한 중복을 피하고자 해보았다.

이번 문제는 해봤자 100*9를 하면 되서 900번의 연산이지만 

숫자가 엄청 커지는거를 대비해서 그냥 이렇게 풀었다. 

 

이번은 우선순위를 정하고, 그 우선순위에 따라서 숫자를 매기면 된다. 

우선순위를 정할 떄 max_element를 이용해서 가장 큰 숫자를 찾는 방법이 있다.

그런데 max_element를 쓰면 사용할때마다 내부에서 정렬하는걸로 알고 있어서 그냥 정렬을 하고 중복인자를 싹다 제거하는게 조금이라도 빠를것 같았다. (찾아봐야함)

그래서 숫자 우선순위순으로 나올 수 있게 하는 temp벡터를 만들었다.

 

그리고 앞에서부터 해당 우선순위에 해당하는 곳부터 차례대로 순서를 매기면 되는데, 다음 우선순위를 정할 때는 가장 마지막에 차례를 매긴곳부터 시작해야 한다. 계속 순환하는거라서 iter을 사용하면 편할것 같다는 생각이 들었다. 

그래서 그렇게 품

iter을 기억해주는 tmpiter을 만들어서 우선순위가 바뀌였을 때는 tmpiter부터 시작하도록 했다.

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int solution(vector<int> priorities, int location) {
	//priorities에 개수를 구함
    int siz = priorities.size();
    //순서를 적어둘 빈 vector생성
    vector<int> order(siz);
    //중복을 최대한 줄이기 위해서 나온 숫자만 추출해서 순서대로 쭉 순서를 매길거
    //아무리 최대로 해봤자 1~9이고 100개 이하의 문서이지만 1000~~~이러면 그냥 반복문을 사용하기는
    //힘들것 같아 이렇게 풀어봄
    vector<int> temp = priorities;								//복사를 하구
    sort(temp.begin(), temp.end(),greater<>());					//정렬을 하고
    temp.erase(unique(temp.begin(), temp.end()), temp.end());	//중복제거
    int next = temp.size();										//이러면 나온 숫자 개수가 나옴
    //반복을 시작하는데 가장 처음부터 할거임
    auto iter = priorities.begin();
    //다음 프린트를 할 때는 가장 마지막에 한 프린터를 기준으로 시작됨.그래서 그 위치를 기억할떄 필요
    auto tmpiter = iter;
	
    //1번 숫자부터 시작하면
    int num = 1;
    

    for(int j=0;j<next;j++){	//나온 숫자의 개수만큼 반복
        iter = tmpiter;       	//가장 최근에 번호가 매겨진 위치임
        for(int i=0;i<siz;i++){			//priorities의 개수만큼 반복
            if(*(iter) == temp[j]){		//현재 번호매기고 있는 수
                tmpiter = iter;			//위치기억
                order[iter-priorities.begin()] = num++;		//순서 확정
                if(order[location]!=0) return order[location];	//확정이 location이면 반환
            }
            //iter이 계속해서 순환하며 돈다
            iter++;		
            if(iter==priorities.end()) 
                iter = priorities.begin();
        }
    }
}

 

 

그래도 숫자 자체가 작아서인지 다 비슷비슷하네 ㅠㅠ 괜히 이짓거리하고있나