---
# System prepended metadata

title: L14-NailingPlanks
tags: [Codility_lessons]

---

# 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;
}
```
