✅Easy Solution | C++ | Mapping + Greedy + BS
Approach

Convert 2D coordinates to 1D values:
Since the points lie on the boundary,
mapping each point to a single value along the perimeter.
The transformatio
# Approach
1. Convert 2D coordinates to 1D values:

    Since the points lie on the boundary, 
    mapping each point to a single value along the perimeter.
    
    #### The transformation is as follows:

    - Left boundary (LD): (x, y) → **`y`** 
    - Top boundary (LU): (x, y) → **`side + x`**
    - Right boundary (RU): (x, y) → **`2 * side + (side - y)`**
    - Bottom boundary (RD): (x, y) → **`3 * side + (side - x)`**

    Sort points in **clockwise** order starting with left, top, right, and bottom.

2. Binary search for the Low between 1 and side.

3. Use **Greedy** and **BS** to ensure that we can select `k` points such that the minimum **Manhattan distance** between any two points is at least `low`.

    ## Greedy: 
     Start with the first point in the sorted `Num` list and attempt to select subsequent points in such a way that the Manhattan distance between **the current point + the previous point is >= low`.**

   ## Binary Search:
     Find the smallest point in `Num` >= `ptr + low`, where `ptr` is the current point.

   **Head and Tail Conditions**:
    - `end` is the farthest point that can be selected.
    - Ensuring that it falls within the range of `[ptr + low, end]`. 

# Complexity
- **Time complexity**: $$O(nlogn + (logs)nk(logn))$$
    
    1. Sorting 1D Num O(nlogn)
    
    2. **BS** on low bounds [1, side] O(logs) 
    
    3. Checking if low is valid O(nklogn)

- **Space complexity**: $$O(n)$$

# Code
```cpp
using ll = long long;

class Solution {
public:
    int maxDistance(int side, vector<vector<int>>& points, int k) {
        // LD (x, y) -> y
        // LU (x, y) -> side + x
        // RU (x, y) -> side * 2 + (side - y)
        // RD (x, y) -> side * 3 + (side - x)

        // 2D transfer to 1D
        vector<ll> Num;
        for (auto& p : points) {
            int x = p[0], y = p[1];

            if (x == 0) Num.push_back(y);
            else if (y == side) Num.push_back(side + x);
            else if (x == side) Num.push_back((ll) side * 3 - y);
            else Num.push_back((ll) side * 4 - x);
        }
        sort(begin(Num), end(Num));
        
        this->Num = Num;

        // Binary Search to find low
        int L = 1, R = side;
        while (L < R) {
            int M = L + (R - L) / 2 + 1;
            if (check(M, side, k)) L = M;
            else R = M - 1;
        }
        return L;
    }
private:
    vector<ll> Num;
    
    bool check(int low, int side, int k) {
        for (ll& start : Num) {

            ll end = start + (ll) 4 * side - low;
            ll ptr = start;

            bool flag = 1;
            for (int i = 0; i < k - 1; i++) {
                int L = 0, R = Num.size() - 1;
                while (L < R) {
                    int M = L + (R - L) / 2;
                    if (Num[M] >= ptr + low) R = M;
                    else L = M + 1;
                }
                if (Num[L] < ptr + low || Num[L] > end) {
                    flag = 0;
                    break;
                }
                ptr = Num[L];
            }
            if (flag) return true;
        }
        return false;
    }
};

['Binary Search', 'Greedy', 'C++']