三十年河东,三十年河西|

自动机

园龄:1年10个月粉丝:2关注:4

Codeforces Round 896 (Div. 2)

C

题意:

构造一个 n * m 的矩阵,要求每一行都是[0, m - 1]的排列,vi 是每一列的MEX
矩阵价值为MEX(v1, v2, v3 ....), 输出最大价值的矩阵

思路:

要想价值最大,那最理想的情况就是每一列的 MEX = [0, 1, ... , m - 1], 这样矩阵价值就是m
比如当 m = 4 时这样的矩阵为:
[1, 2, 3, 0]
[2, 3, 0, 1]
[3, 0, 1, 2]
就是把[0, m - 1]不断循环左移,这样的话 n = m - 1;
那 n < m - 1 怎么办?
其实就是在上面的情况下删掉一些行,那么MEX = [0, 1, ... , m - 1]就会少几个,那最大就是 n + 1;
那 n > m - 1 怎么办?
其实只需要一直重复第一行就行了,这样就不会改变MEX

inline void solve() 
{
    int n, m; cin >> n >> m;
    if (m == 1)
    {
        cout << '0' << endl;
        for (int i = 1; i <= n; i++)
            cout << 0 << endl;
        return; 
    }
    else cout << min(n + 1, m) << endl;

    int idx = 1;
    std::vector<int> a;
    for (int i = 0; i < m; i++)
        a.pb(i);
    for (int i = 1; i <= n; i++)
    {

        if (i > m - 1)
        {
            idx = 1;
            cout << a[idx] << ' ';
            for (int j = (idx + 1) % m; j != idx; j = (j + 1) % m)
                cout << a[j] << ' ';
            cout << endl;
            continue;
        }

        cout << a[idx] << ' ';
        for (int j = (idx + 1) % m; j != idx; j = (j + 1) % m)
            cout << a[j] << ' ';
        cout << endl;

        idx = (idx + 1) % m;
    }
}

D1

题意:

n个人每个人都有a[i]个糖果,每个人都需要别人2x个糖果,并收到别人给的2y糖果, 问最后能不能让每个人的糖果一样多

思路:

很容易想到每个人最后的糖果个数一定是平均值ave, 那么|a[i] - ave| = 2y - 2x 一定是2的幂次,并且所有人给出去的糖果和收到的糖果一定相等

inline void solve() 
{
    int n; cin >> n;
    std::vector<int> a(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];

    LL s = accumulate(a.begin(), a.end(), LL(0));

    if (s % n)
    {
        cout << "NO" << endl;
        return;
    }

    LL ave = s / n;
    std::vector<int> cnt(31, 0);
    for (int i = 0; i < n; i++)
    {
        if (a[i] < ave)
        {
            int d = ave - a[i];
            int l = __builtin_ctz(d);
            cnt[l]++;

            d += 1 << l;
            if (d & (d - 1))
            {
                cout << "NO" << endl;
                return;
            }

            cnt[__builtin_ctz(d)]--;
        }
        else if (a[i] > ave)
        {
            int d = a[i] - ave;
            int l = __builtin_ctz(d);
            cnt[l]--;

            d += 1 << l;
            if (d & (d - 1))
            {
                cout << "NO" << endl;
                return;
            }

            cnt[__builtin_ctz(d)]++;
        }
    }

    for (int i = 0; i < 31; i++)
        if (cnt[i])
        {
            cout << "NO" << endl;
            return;
        }
    cout << "YES" << endl;
}

本文作者:自动机

本文链接:https://www.cnblogs.com/monituihuo/articles/17697675.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   自动机  阅读(4)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起