https://programmers.co.kr/learn/courses/30/lessons/60062
코딩테스트 연습 - 외벽 점검
레스토랑을 운영하고 있는 "스카피"는 레스토랑 내부가 너무 낡아 친구들과 함께 직접 리모델링 하기로 했습니다. 레스토랑이 있는 곳은 스노우타운으로 매우 추운 지역이어서 내부 공사를 하
programmers.co.kr
- 제한사항에 주어진 배열들 길이가 다 짧아서 바 로 완전탐색 로직을 생각해냈다.
다만 취약지점을 순회하는 방식을 생각해내기가 좀 어려웠던 문제이다.
- weak의 길이를 2배로 늘리고 기존 weak.size()+1부터 기존의 값 + n인 값을 넣어주고 이 안에서 weak.size() 개수만큼 취약지점을 순회하게 되면 순회를 종료하는 식으로 로직을 짰다.
- 친구들을 투입하는 순서를 완전탐색으로 모두 넣어본 뒤 그 케이스 중 최소인원을 리턴하면 된다.
- upper_bound를 사용하면 기존 순회했던 위치보다 더 크면서 그 중 제일 작은 값을 쉽게 구할 수 있다.(python의 bisect) 내부는 이분탐색으로 구현되어있음.
**upper_bound: 상한, 큰 수 중 첫 번째 수 리턴, lower_bound: 하한, 크거나 같은 수 중 첫번째 수 리턴
** k의 상한의 위치 - k의 하한의 위치 = 가능한 k의 갯수
#include <algorithm>
#define INF 987654321
using namespace std;
int solution(int n, vector<int> weak, vector<int> dist) {
int ans = INF;
int wLen = weak.size();
int dLen = dist.size();
weak.resize(wLen * 2);
for (int i = wLen; i < 2 * wLen; ++i) {
weak[i] = n + weak[i - wLen];
} // [1,5,6,10, 13,17,18,22] 여기서 4개 점검하면 됨
sort(dist.begin(), dist.end());
do { // dist: 1234, 1243, 1324, 1342...
for (int i = 0; i < wLen; ++i) {
int s = weak[i], e = weak[i + wLen - 1];
int cnt = 0;
for (int j = 0; j < dLen; ++j) {
s += dist[j];
++cnt;
if (s >= e) {
ans = min(ans, cnt);
break;
}
// s보다 큰 weak[j] 중에 제일 작은값
int nIdx = upper_bound(weak.begin(), weak.end(), s) - weak.begin();
s = weak[nIdx];
}
}
} while (next_permutation(dist.begin(), dist.end()));
return ans == INF ? -1 : ans;
}
'Algorithm > programmers' 카테고리의 다른 글
2021 Kakao blind 72412 - 순위 검색(문자열 파싱, 비트마스킹, 이진탐색) c++ 풀이 (0) | 2021.09.06 |
---|---|
2021 Kakao blind 72411 - 메뉴 리뉴얼(브루트포스, 해쉬) c++, java 풀이 (0) | 2021.09.06 |
2021 Kakao blind - 신규 아이디 추천(문자열 파싱) javascript, Java 풀이 (0) | 2021.09.06 |
프로그래머스 2021 Dev-Matching 77486 - 다단계 칫솔 판매(트리 순회) (0) | 2021.08.13 |
[kakao blind 2020] 문자열 압축 - 문자열, 구현 (0) | 2021.05.14 |