반응형
1. 문제
You are given two non-empty arrays A and B consisting of N integers. These arrays represent N planks.
More precisely, A[K] is the start and B[K] the end of the K−th plank.
Next, you are given a non-empty array C consisting of M integers. This array represents M nails. More precisely, C[I] is the position where you can hammer in the I−th nail.
We say that a plank (A[K], B[K]) is nailed if there exists a nail C[I] such that A[K] ≤ C[I] ≤ B[K].
The goal is to find the minimum number of nails that must be used until all the planks are nailed. In other words, you should find a value J such that all planks will be nailed after using only the first J nails. More precisely, for every plank (A[K], B[K]) such that 0 ≤ K < N, there should exist a nail C[I] such that I < J and A[K] ≤ C[I] ≤ B[K].
For example, given arrays A, B such that:
A[0] = 1 B[0] = 4
A[1] = 4 B[1] = 5
A[2] = 5 B[2] = 9
A[3] = 8 B[3] = 10
four planks are represented: [1, 4], [4, 5], [5, 9] and [8, 10].
Given array C such that:
C[0] = 4
C[1] = 6
C[2] = 7
C[3] = 10
C[4] = 2
if we use the following nails:
- 0, then planks [1, 4] and [4, 5] will both be nailed.
- 0, 1, then planks [1, 4], [4, 5] and [5, 9] will be nailed.
- 0, 1, 2, then planks [1, 4], [4, 5] and [5, 9] will be nailed.
- 0, 1, 2, 3, then all the planks will be nailed.
Thus, four is the minimum number of nails that, used sequentially, allow all the planks to be nailed.
Write a function:
int solution(vector<int> &A, vector<int> &B, vector<int> &C);
that, given two non-empty arrays A and B consisting of N integers and a non-empty array C consisting of M integers, returns the minimum number of nails that, used sequentially, allow all the planks to be nailed.
If it is not possible to nail all the planks, the function should return −1.
For example, given arrays A, B, C such that:
A[0] = 1 B[0] = 4
A[1] = 4 B[1] = 5
A[2] = 5 B[2] = 9
A[3] = 8 B[3] = 10
C[0] = 4
C[1] = 6
C[2] = 7
C[3] = 10
C[4] = 2
the function should return 4, as explained above.
Write an efficient algorithm for the following assumptions:
- N and M are integers within the range [1..30,000];
- each element of arrays A, B and C is an integer within the range [1..2*M];
- A[K] ≤ B[K].
주어진 못으로, 못질을 할 때, 언제 모든 판자에 못을 박을 수 있는지 구하는 문제. (못을 순서대로 써야 한다)
예시) return 4
| [0] | [1] | [2] | [3] | [4] | |
| A (판자 시직 위치) | 1 | 4 | 5 | 8 | |
| B (판자 종료 위치) | 4 | 5 | 9 | 10 | |
| C (못 위치) | 4 | 6 | 7 | 10 | 2 |
판자 = [1, 4] / [4, 5] / [5, 9] / [8, 10]
첫번째, C[0] 못을 박는다.
판자 [1, 4] 와 [4, 5]에 못이 박힌다.
두번째, C[1] 못을 박는다
판자 [5, 9]에 못이 박힌다.
세번째, C[2] 못을 박는다.
판자 [5, 9]에 못이 박히지만, 이미 C[1]에 의해서 못이 박혀 있다.
네번째, C[3] 못을 박는다.
판자 [8, 10] 에 못이 박힌다. 이로써 모든 판자에 못이 박혔다. (사용한 못 4개, return 4)
2. 매개변수 조건
- vector A, B 크기(N): 1 ~ 30,000
- vector C 크기(M) : 1 ~ 30,000
- vector A, B, C 요소 값 범위: 1 ~ M * 2
3. 코드 (C++)
판자들을 map으로 정리했다.
판자가 같은 위치에서 시작할 수 있으므로, multimap을 사용했다.
map으로 판자들을 정리한 이유는,
판자의 위치가 정렬되어 있으면, 현재 못(C[i])이 모든 판자에 박을 수 있는지 확인할 필요가 없기 때문이다.
#include <map>
int solution(vector<int> &A, vector<int> &B, vector<int> &C) {
multimap<int, int> planks = {};
for(size_t i = 0; i < A.size(); i++)
{
planks.insert({A[i], B[i]});
}
int i = 0;
for(i = 0; i < (int)C.size(); i++)
{
auto it = planks.begin();
while(it != planks.end())
{
if(C[i] < it->first) break; //현재의 못으로는 더 못질할 수 없다
if(it->first <= C[i] && C[i] <= it->second)
{
it = planks.erase(it); //못질이 되면 삭제한다
if(planks.empty()) break;
}
else
{
it++;
}
}
if(planks.empty()) break;
}
if(planks.empty()) return i + 1;
return -1;
}
4. 결과

반응형
'Algorithm Problem > Codility' 카테고리의 다른 글
| Lesson 14. Binary search algorithm - NailingPlanks #3 (속도 개선) (0) | 2025.03.01 |
|---|---|
| Lesson 14. Binary search algorithm - NailingPlanks #2 (속도 개선) (0) | 2025.03.01 |
| Lesson 14. Binary search algorithm - MinMaxDivision (0) | 2025.02.15 |
| Lesson 13. Fibonacci numbers - Ladder (0) | 2025.02.08 |
| Lesson 13. Fibonacci numbers - FibFrog #7 (속도 개선) (0) | 2025.01.27 |