1. Concise Problem Statement  
Given N robbers, they agreed that robber i should receive Xi/Y of the loot. In reality they have M indivisible coins (M may not be divisible by Y). Assign each robber an integer Ki (sum of all Ki = M) to minimize the total unfairness  
   unfairness = ∑ |Xi/Y – Ki/M|.  
Output the Ki that achieve the minimum total unfairness.

2. Detailed Editorial  

Problem restatement and transformation  
- Ideal (real-valued) share for robber i is  
     a_i* = (Xi / Y)·M = Xi·M / Y.  
- We must choose integer Ki ≥ 0 with ∑Ki = M to approximate a_i*.  
- The contribution to unfairness from i is  
     |Xi/Y – Ki/M| = (1/M)·|a_i* – Ki|.  
- Minimizing ∑|Xi/Y – Ki/M| is equivalent to minimizing ∑|a_i* – Ki|.

Key observation:  
- For each i, the best integer Ki is either floor(a_i*) or ceil(a_i*).  
- Let f_i = ⌊a_i*⌋, c_i = ⌈a_i*⌉ = f_i or f_i+1.  
- If we choose Ki = f_i, the error is ε_i(floor) = a_i* – f_i = frac_i.  
  If we choose Ki = c_i, the error is ε_i(ceil) = c_i – a_i* = 1 – frac_i (unless frac_i=0).  
- The difference Δ_i in total error between picking ceil vs floor is  
     Δ_i = ε_i(ceil) – ε_i(floor)  
         = (1 – frac_i) – frac_i  
         = 1 – 2·frac_i.  
- A smaller Δ_i means that ceil gives a bigger reduction in error compared to floor; equivalently, larger frac_i favors choosing the ceil.

Global constraint:  
- Let S = ∑ f_i.  Since ∑ a_i* = M exactly, we have S ≤ M and ∑ c_i ≥ M.  
- We need exactly M coins, so we must “promote” exactly B = M – S of the indices from floor to ceil.  

Algorithm  
1. Compute for each i:  
   a_i* = Xi·M / Y (as double),  
   f_i = ⌊a_i*⌋,  frac_i = a_i* – f_i.  
2. Compute S = ∑ f_i, let B = M – S.  
3. Sort indices i in descending order of frac_i (or equivalently ascending order of Δ_i = 1–2·frac_i).  
4. For the top B indices, set Ki = f_i + 1; for the rest, Ki = f_i.  
5. Output the array K.  

Complexity  
- O(N) to compute floors and fractions, O(N log N) to sort, O(N) to build the answer. Works for N up to 1000.

3. C++ Solution

```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

int n, m, y;
vector<int> x;

void read() {
    cin >> n >> m >> y;
    x.resize(n);
    cin >> x;
}

void solve() {
    // x[i] / y = a[i] / m

    vector<int> a_floor(n), a_ceil(n);
    vector<double> delta(n);

    int sum_floor = 0;
    for(int i = 0; i < n; i++) {
        a_floor[i] = (x[i] * m) / y;
        a_ceil[i] = (x[i] * m + y - 1) / y;

        sum_floor += a_floor[i];
        if(a_floor[i] == a_ceil[i]) {
            continue;
        }

        double a_exact = (double)x[i] * m / y;
        delta[i] = -(a_exact - a_floor[i]) + (a_ceil[i] - a_exact);
    }

    int buffer = m - sum_floor;

    vector<int> perm(n);
    iota(perm.begin(), perm.end(), 0);
    sort(perm.begin(), perm.end(), [&](int i, int j) {
        return delta[i] < delta[j];
    });

    assert(buffer <= n);
    for(int i = 0; i < buffer; i++) {
        a_floor[perm[i]] = a_ceil[perm[i]];
    }

    cout << a_floor << '\n';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

4. Python Solution with Detailed Comments  

```python
import sys

def main():
    data = sys.stdin.read().split()
    it = iter(data)
    n = int(next(it))
    m = int(next(it))
    y = int(next(it))
    x = [int(next(it)) for _ in range(n)]

    # Compute floor, fractional parts, and prepare for sorting
    floors = [0]*n
    fracs  = [0.0]*n
    sum_floor = 0

    for i in range(n):
        # ideal real share times M
        exact = x[i]*m / y
        f = int(exact)           # floor
        sum_floor += f
        floors[i] = f
        fracs[i] = exact - f     # fractional part in [0,1)

    # buffer = how many 1-coin increments we need
    buffer = m - sum_floor

    # Pair each index with its fractional part
    # We want the largest fractional parts first
    idx = list(range(n))
    idx.sort(key=lambda i: fracs[i], reverse=True)

    # Promote the top 'buffer' floors to floors+1
    for k in range(buffer):
        i = idx[k]
        floors[i] += 1

    # Output the result
    print(*floors)

if __name__ == "__main__":
    main()
```

5. Compressed Editorial  
- Compute ideal real shares a_i* = Xi·M/Y.  
- Let f_i = ⌊a_i*⌋, sum S = ∑f_i. Buffer = M–S.  
- Fraction frac_i = a_i*–f_i.  
- Increase to ⌈a_i*⌉ exactly Buffer robbers with largest frac_i.