# L14-NailingPlanks
###### tags: `Codility_lessons`
## Question
https://app.codility.com/programmers/lessons/14-binary_search_algorithm/nailing_planks/
## Key
1. 要釘幾個釘子才能將板子牢固,用二分搜尋找釘子數目mid =( 0 + C.size())/2
2. 問題是要怎麼確認釘子符合A[k] <= C[i]<= B[k],第一個方法兩個while loop,才能在不符合時,讓C移動到下一個再試一次
3. 第二個方法是類似prefix sum,利用一個陣列將所有C[i]出現過的點都記錄為1,並進行壘加,如果在A[K]和B[k]的位置間有C[i]出現,那麼陣列在位置B[k]和A[k]-1的累加值不會一樣,反之,會一樣,此時舅就要換下一個C[i]進行嘗試,假設到mid還不符合,代表釘子數目太小,要增加
## Reference
## Solution
### Sol. I
```cpp=
def check(A, B, C, K):
# sort the nails if the positions are random
C.sort()
C_len = len(C)
A_len = len(A)
i = 0
j = 0
while K > 0 and i < C_len:
while j < A_len:
if A[j] <= C[i] <= B[j]:
j += 1
else:
break
K -= 1
i += 1
if K < 0 or j < A_len:
return False
else:
return True
```
### Sol. II
```cpp=
bool nailed(vector<int>& A, vector<int>& B, vector<int>& C, int maxNails) {
int n = A.size();
int m = C.size();
vector<int> nailsCounter(m * 2 + 1, 0);
for (int i = 0; i < maxNails; ++i) {
nailsCounter[C[i]] = 1;
}
int counter = 0;
for (auto &v: nailsCounter) {
counter += v;
v = counter;
}
for (int i = 0; i < n; ++i) {
if (nailsCounter[A[i] - 1] == nailsCounter[B[i]]) return false;
}
return true;
}
int solution(vector<int>& A, vector<int>& B, vector<int>& C) {
int lower = 1, upper = C.size();
if (!nailed(A, B, C, upper)) return -1;
while (lower < upper) {
int nails = (lower + upper) / 2;
if (nailed(A, B, C, nails)) upper = nails;
else lower = nails + 1;
}
return lower;
}
```