← 返回题目页

A1869 [USACO08JAN] iCow B

标程

#include <bits/stdc++.h>
using namespace std;

// [USACO08JAN] iCow B
//
// 模拟播放顺序:
//   1. 选权值最大的曲子(权值相同则选编号最小的);
//   2. 输出它的编号;
//   3. 设它的权值为 W:其余 N-1 首每首先得到 W / (N-1),
//      余数 W % (N-1) 以 1 为单位,按编号从小到大(跳过刚播过的那首)依次多分;
//      刚播过的那首权值清零。
//
// N、T <= 1000,直接 O(NT) 模拟即可。

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

    int N, T;
    cin >> N >> T;

    vector<long long> R(N + 1);
    for (int i = 1; i <= N; i++) cin >> R[i];

    for (int t = 0; t < T; t++) {
        // 选权值最大的;权值相同则选编号最小的
        int k = 1;
        for (int i = 2; i <= N; i++) {
            if (R[i] > R[k]) k = i;
        }
        cout << k << "\n";

        long long W = R[k];
        R[k] = 0;
        if (N == 1) continue;  // 只有一首曲子,没有别人可分

        long long share = W / (N - 1);
        long long rem = W % (N - 1);
        for (int i = 1; i <= N; i++) {
            if (i != k) R[i] += share;
        }
        // 余数按编号从小到大依次多分,跳过刚播过的那首
        for (int i = 1; i <= N && rem > 0; i++) {
            if (i == k) continue;
            R[i] += 1;
            rem--;
        }
    }
    return 0;
}

动画演示