Note this smart observation from Editorial: "M will be either P or Q or (A_i+A_j)/2"..
Yea I know, my code is not condense enough..
#include <cmath> #include <cstdio> #include <cmath> #include <climits> #include <cctype> #include <vector> #include <string> #include <iostream> #include <algorithm> #include <unordered_map> using namespace std; int inRange(int p, int q, int v) { return v >= p && v <= q; } int main() { int n; cin >> n; vector<int> in(n); for (int i = 0; i < n; i++) cin >> in[i]; std::sort(in.begin(), in.end()); int p, q; cin >> p >> q; int dist = INT_MIN; int v = -1; if (q < in[0]) { v = q; } else if (p > in.back()) { v = p; } else { auto it_p = std::lower_bound(in.begin(), in.end(), p); // Check P's if (it_p != in.end()) { int dist_p1 = *it_p - p; // p-->in[i] int dist_p0 = INT_MAX; // in[i]-->p if (it_p != in.begin()) { auto it_pp = it_p - 1; dist_p0 = p - *(it_pp); int mid = (*it_pp + *it_p) / 2; if (mid > p) it_p = it_pp; } dist = std::min(dist_p0, dist_p1); v = p; } auto it_q = std::upper_bound(in.begin(), in.end(), q); // Check mid-points for (auto it = it_p; it != it_q; it++) { int mid = (*it + *(it + 1)) / 2; int newdist = (*(it + 1) - *it) / 2; if (inRange(p, q, mid) && (newdist > dist)) { dist = newdist; v = mid; } } // Q's int newdist_q = INT_MIN; if (it_q == in.end()) { newdist_q = q - in.back(); } else if (it_q != in.begin()) { newdist_q = std::min(q - *(it_q - 1), *it_q - q); } if (newdist_q > dist) { dist = newdist_q; v = q; } } cout << v << endl; return 0; }