You are given an integer side, representing the edge length of a square with corners at (0, 0), (0, side), (side, 0), and (side, side) on a Cartesian plane.
You are also given a positive integer k and a 2D integer array points, where points[i] = [xi, yi] represents the coordinate of a point lying on the
boundary of the square.
You need to select k elements among points such that the minimum Manhattan distance between any two points is maximized.
Return the maximum possible minimum Manhattan distance between the selected k points.
The Manhattan Distance between two cells (xi, yi) and (xj, yj) is |xi -xj| + |yi - yj|.
Input: side =2, points =[[0,2],[2,0],[2,2],[0,0]], k =4Output: 2Explanation:

Select all four points.
Input: side =2, points =[[0,0],[1,2],[2,0],[2,2],[2,1]], k =4Output: 1Explanation:

Select the points `(0, 0)`,`(2, 0)`,`(2, 2)`, and `(2, 1)`.
Input: side =2, points =[[0,0],[0,1],[0,2],[1,2],[2,0],[2,2],[2,1]], k =5Output: 1Explanation:

Select the points `(0, 0)`,`(0, 1)`,`(0, 2)`,`(1, 2)`, and `(2, 2)`.
To maximize the minimum Manhattan distance between any two selected points, we can use binary search on the answer. For each candidate distance, we greedily try to select points such that every new point is at least that far from all previously selected points.
Map all points to a 1D representation of their position along the square’s boundary (since all points are on the boundary, the Manhattan distance between two points is the distance along the boundary).
Sort the mapped positions.
Use binary search for the answer between 0 and the perimeter of the square.
For each mid value, try to greedily select points such that each is at least mid away from the previous selected point (wrapping around the perimeter if needed).
If possible to select k points, try a larger value; otherwise, try smaller.
Return the largest value for which it is possible.
classSolution {
public:int maximizeDistance(int side, vector<vector<int>>& points, int k) {
int n = points.size();
vector<int> pos;
int perim =4* side;
for (auto& p : points) {
int x = p[0], y = p[1];
if (y ==0) pos.push_back(x);
elseif (x == side) pos.push_back(side + y);
elseif (y == side) pos.push_back(3* side - x);
else pos.push_back(4* side - y);
}
sort(pos.begin(), pos.end());
int l =0, r = perim, ans =0;
while (l <= r) {
int m = (l + r) /2;
int cnt =1, last = pos[0];
for (int i =1; i < n; ++i) {
if (pos[i] - last >= m) {
cnt++;
last = pos[i];
}
}
if (perim - last + pos[0] >= m) cnt++;
if (cnt >= k) { ans = m; l = m +1; }
else r = m -1;
}
return ans;
}
};
classSolution {
publicintmaximizeDistance(int side, int[][] points, int k) {
int n = points.length, perim = 4 * side;
int[] pos =newint[n];
for (int i = 0; i < n; i++) {
int x = points[i][0], y = points[i][1];
if (y == 0) pos[i]= x;
elseif (x == side) pos[i]= side + y;
elseif (y == side) pos[i]= 3 * side - x;
else pos[i]= 4 * side - y;
}
Arrays.sort(pos);
int l = 0, r = perim, ans = 0;
while (l <= r) {
int m = (l + r) / 2, cnt = 1, last = pos[0];
for (int i = 1; i < n; i++) {
if (pos[i]- last >= m) {
cnt++;
last = pos[i];
}
}
if (perim - last + pos[0]>= m) cnt++;
if (cnt >= k) { ans = m; l = m + 1; }
else r = m - 1;
}
return ans;
}
}
classSolution {
funmaximizeDistance(side: Int, points: Array<IntArray>, k: Int): Int {
val n = points.size
val perim = 4 * side
val pos = IntArray(n)
for (i in0 until n) {
val(x, y) = points[i]
pos[i] = when {
y ==0-> x
x == side -> side + y
y == side ->3 * side - x
else->4 * side - y
}
}
pos.sort()
var l = 0var r = perim
var ans = 0while (l <= r) {
val m = (l + r) / 2var cnt = 1var last = pos[0]
for (i in1 until n) {
if (pos[i] - last >= m) {
cnt++ last = pos[i]
}
}
if (perim - last + pos[0] >= m) cnt++if (cnt >= k) {
ans = m
l = m + 1 } else {
r = m - 1 }
}
return ans
}
}
classSolution:
defmaximizeDistance(self, side: int, points: list[list[int]], k: int) -> int:
n = len(points)
perim =4* side
pos = []
for x, y in points:
if y ==0:
pos.append(x)
elif x == side:
pos.append(side + y)
elif y == side:
pos.append(3* side - x)
else:
pos.append(4* side - y)
pos.sort()
l, r, ans =0, perim, 0while l <= r:
m = (l + r) //2 cnt, last =1, pos[0]
for i in range(1, n):
if pos[i] - last >= m:
cnt +=1 last = pos[i]
if perim - last + pos[0] >= m:
cnt +=1if cnt >= k:
ans = m
l = m +1else:
r = m -1return ans
impl Solution {
pubfnmaximize_distance(side: i32, points: Vec<Vec<i32>>, k: i32) -> i32 {
let n = points.len();
let perim =4* side;
letmut pos =vec![];
for p in&points {
let (x, y) = (p[0], p[1]);
pos.push(if y ==0 {
x
} elseif x == side {
side + y
} elseif y == side {
3* side - x
} else {
4* side - y
});
}
pos.sort();
let (mut l, mut r, mut ans) = (0, perim, 0);
while l <= r {
let m = (l + r) /2;
letmut cnt =1;
letmut last = pos[0];
for&p in pos.iter().skip(1) {
if p - last >= m {
cnt +=1;
last = p;
}
}
if perim - last + pos[0] >= m {
cnt +=1;
}
if cnt >= k {
ans = m;
l = m +1;
} else {
r = m -1;
}
}
ans
}
}