zoukankan      html  css  js  c++  java
  • CodeForces673 Div.2 D

    CodeForces673 Div.2 D - Make Them Equal 思维,构造

    题意

    给定正数数组(a),长度为(n)

    要求在(3n)次操作内使数组的值都相等。

    操作描述如下:

    任何操作结束后必须保证所有元素非负

    [1.选择i,j,x.其中1leq i leq jleq n.0leq xle 10^9\ 2.使得a_i -= x * i,a_j += x * i ]

    [0 leq k leq 3n\ 1leq a_i leq 10^5 ]

    分析

    贪心方案如下:

    • (2-n)的数组变为(i)的倍数
    • 把这些数加给(a_1)
    • (a_1)分配给其他数

    难点在于如何使每次操作后元素保持非负数,并且使得元素是(i)的倍数。

    不妨令

    [a_1 = a_1 - (i - a_i \% i)\ a_i = a_i + (i - a_i \% i) ]

    容易通过数学归纳法证明这个构造方法。

    代码

    int a[10005];
    
    struct S {
        int i, j;
        ll x;
        S(int _i, int _j, ll _x) {
            i = _i;
            j = _j;
            x = _x;
        }
    };
    
    void go(int x, int y, int val) {
        a[x] -= x * val;
        a[y] += x * val;
    }
    
    void solve() {
        int n = readint();
        ll sum = 0;
        for (int i = 1; i <= n; i++)
            a[i] = readint(), sum += a[i];
        if (sum % n) {
            puts("-1");
            return;
        }
        ll num = sum / n;
        vector<S> res;
        for (int i = 2; i <= n; i++) {
            if (a[i] % i) {
                res.push_back(S(1, i, i - a[i] % i));
                go(1, i, i - a[i] % i);
            }
            res.push_back(S(i, 1, a[i] / i));
            go(i, 1, a[i] / i);
        }
        for (int i = 2; i <= n; i++) {
            res.push_back(S(1, i, num));
            go(1, i, num);
        }
        cout << res.size() << '
    ';
        for (int i = 0; i < res.size(); i++)
            cout << res[i].i << ' ' << res[i].j << ' ' << res[i].x << '
    ';
    }
    
    
    int main() {
        int T = readint();
        while (T--) solve();
    }
    
  • 相关阅读:
    将16进制的颜色值变成UIColor
    验证邮箱地址方法
    iOS 推送通知详解
    在UITextView中添加placeholder
    移除所有子视图removeAllSubviews
    如何书写高质量的jQuery代码
    reset.css
    CSS3笔记
    10个可以直接拿来用的JQuery代码片段
    js定时器
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13756061.html
Copyright © 2011-2022 走看看