https://www.welcomekakao.com/learn/courses/30/lessons/42891
정확성 테스트는, 그냥 조건대로 시뮬레이션을 돌리면 통과할 수 있지만, 효율성 테스트는 통과할 수 없다.
k의 범위가 매우 큰데, 나이브하게 풀면 k번 탐색해야하기 때문이다.
k번 탐색할 게 아니라, 최대로 음식의 개수만큼만 탐색하도록 구현할 수 있다.
음식을 먹는 데 소요되는 시간을 오름차순으로 정렬하고,
(현 시점에서 가장 적은 시간이 소요되는 음식의 시간 * 남아있는 음식의 수)만큼의 시간을 한 번에 감소시킬 수 있다.
당연히 k도 갱신되어야 하고, 위에 계산한 시간이 k보다 작아야 가능하다.
저 시간이 k보다 크다면, 음식별 소요 시간으로 정렬해 두었던 것을, 다시 본래의 인덱스로 돌려준다. 이것 때문에 초반에 pair에 음식별 소요시간과 그 음식의 번호를 함께 저장하는 것이다.
이제는 나머지 연산을 활용해서, 먹어야할 음식을 찾아주면 된다.
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 | #include <string> #include <vector> #include<iostream> #include<algorithm> using namespace std; typedef pair<int, int> pii; typedef long long ll; bool cmp(pii a, pii b) { return a.second < b.second; } int solution(vector<int> ft, long long k) { vector<pii> foods; for (int i = 0; i < ft.size(); i++) foods.push_back({ ft[i], i + 1 }); //음식의 번호는 1부터 sort(foods.begin(), foods.end()); int remain = foods.size(); ll spend, preTime = 0; //spend = 현 시점에서 한번에 지울 수 있는 시간, pretime = 이전에 봤던 음식의 소요 시간 for (vector<pii>::iterator itr = foods.begin(); itr != foods.end(); itr++, remain--) { spend = (itr->first-preTime) * remain; preTime = itr->first; if (spend == 0) continue; else if (spend <= k) { //한번에 spend만큼 지울 수 있으면 k -= spend; } else { //한번에 먹을 수 있는 양보다 k가 작으면 sort(itr, foods.end(), cmp);//다시 음식들 원위치로 정렬 k %= remain; return (itr + k)->second; } } return -1; //먹을 수 있는 게 없어서, spend가 k보다 커진적 없이, 계속 0이라 스킵된 경우 } int main(void) { vector<int> v; v = { 3,5,1,6,5,3 }; int k = 20; solution(v, 20); return 0; } | cs |
'알고리즘 문제 풀이 > 프로그래머스' 카테고리의 다른 글
카카오 2017 블라인드 테스트 1차: 다트 게임 (C++) (0) | 2019.08.25 |
---|---|
2017 카카오 블라인드 테스트 1차: 비밀지도 (C++) (0) | 2019.08.23 |
카카오 2018 블라인드 테스트: 길 찾기 게임 C++ (0) | 2019.08.20 |
카카오 2018 블라인드 테스트: 실패율 C++ (0) | 2019.08.19 |
카카오 2018 블라인드 테스트: 오픈채팅방 C++ (0) | 2019.08.19 |