/*
 * Same algorithm in idiomatic C++: flatten into std::vector<int>, ensure every value
 * shares grid[0][0] % x, sort, take the median, then sum |a[i] - median| / x.
 * std::vector handles memory; std::nth_element / std::sort do the heavy lifting.
 */

#include <vector>      // std::vector 動態陣列 / dynamic array container
#include <algorithm>   // std::sort, std::abs 等演算法 / algorithms
#include <cstdint>     // int64_t 64-bit integer

class Solution {
public:
    int minOperations(std::vector<std::vector<int>>& grid, int x) {
        // 把所有元素丟進一維 vector / flatten the 2-D grid into one vector
        std::vector<int> a;
        // reserve 預先配置空間，避免 push_back 反覆重新配置 / pre-allocate capacity
        a.reserve(static_cast<size_t>(grid.size()) * grid[0].size());

        int rem = grid[0][0] % x;   // 餘數基準 / baseline remainder

        // range-for: 直接走訪每一列；用 const 參考避免複製 / iterate rows by const ref
        for (const auto& row : grid) {
            for (int v : row) {                 // 走訪每個值 / iterate each value
                if (v % x != rem) return -1;    // 餘數不同就不可能 / impossible
                a.push_back(v);                 // 加入攤平陣列 / append to flat array
            }
        }

        // std::sort 預設升序，需要 #include <algorithm> / sorts a in ascending order
        std::sort(a.begin(), a.end());

        int median = a[a.size() / 2];   // 中位數 / median element

        // 用 long long (即 int64_t) 累加避免溢位 / 64-bit accumulator avoids overflow
        long long sum = 0;
        for (int v : a) {
            sum += std::abs(v - median);   // std::abs 取絕對值 / absolute difference
        }

        // 每步移動 x，故總步數 = 距離和 / x / each step shifts by x
        return static_cast<int>(sum / x);
    }
};
