牛客周赛 Round 123

链接:https://ac.nowcoder.com/acm/contest/125954

A – 小红玩牌

算法:

    模拟。

思路:

    无。

关键代码:

void miyan()
{
    int a, c;
    char b, d;
    cin >> a >> b >> c >> d;

    if (a > c)
        cout << "Yes" << endl;
    else if (a < c)
        cout << "No" << endl;
    else
    {
        if (b < d)
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
}

B – 小红作弊

算法:

    模拟。

思路:

    无。

关键代码:

void miyan()
{
    int a[13];
    for (int i = 0; i < 13; ++i)
        cin >> a[i];

    int ans = 0;
    for (int i = 0; i < 13; ++i)
    {
        int x;
        cin >> x;

        ans += max(0, x + a[i] - 4);
    }

    cout << ans << endl;
}

C – 小红出对

算法:

    模拟。

思路:

    无。

关键代码:

void miyan()
{
    int n;
    cin >> n;
    map<pair<int, char>, int> m;
    map<pair<int, char>, vector<int>> hash;
    for (int i = 0; i < n; ++i)
    {
        int x;
        char c;
        cin >> x >> c;
        ++m[{x, c}];
        hash[{x, c}].push_back(i + 1);
    }

    map<int, priority_queue<pair<char, int>, vector<pair<char, int>>, greater<>>> mq;
    for (auto [x, y] : m)
        mq[x.first].push({x.second, y});

    int ans = 0;
    vector<pii> res;
    for (auto [val, q] : mq)
    {
        while (q.size() >= 2)
        {
            auto [_, cnt1] = q.top();
            q.pop();
            auto [__, cnt2] = q.top();
            q.pop();

            int cur1 = cnt1, cur2 = cnt2;
            int t = 1;
            ans += t;
            cur1 -= t;
            cur2 -= t;
            int a = hash[{val, _}].back();
            hash[{val, _}].pop_back();
            int b = hash[{val, __}].back();
            hash[{val, __}].pop_back();

            res.push_back({a, b});
        }
    }

    cout << ans * 2 << endl;
    for (auto [x, y] : res)
        cout << x << ' ' << y << endl;
}

D – 小红打牌

算法:

    组合数学,逆元。

思路:

    枚举每个满足 \(cnt_i, cnt_{i + 1} \le 3\) 的 \(i\),剩下的 \(4\) 个考虑选择相同的或者不同的即可。

关键代码:

ll qmi(ll a, ll b, ll p)
{
    ll ans = 1 % p;
    while (b)
    {
        if (b & 1)
            ans = ans * a % p;
        b >>= 1;
        a = a * a % p;
    }

    return ans;
}

ll inv(ll q, ll mod)
{
    return qmi(q, mod - 2, mod);
}

void miyan()
{
    int n;
    cin >> n;
    vector<ll> cnt(N, 0);
    for (int i = 0; i < n; ++i)
    {
        int x;
        cin >> x;
        ++cnt[x];
    }

    ll val1 = 0, val2 = 0;
    for (int i = 1; i < N; ++i)
    {
        if (cnt[i] >= 2)
            ++val1;
        if (cnt[i] >= 4)
            ++val2;
    }

    ll ans = 0;
    for (int i = 1; i < N - 1; ++i)
    {
        if (cnt[i] < 3 || cnt[i + 1] < 3)
            continue;

        ll t1 = val1 - 2;
        ll t2 = val2;

        if (cnt[i] > 3)
            --t2;
        if (cnt[i + 1] > 3)
            --t2;

        ll cur = 0;
        if (val1 >= 2)
            cur = (cur + t1 * (t1 - 1) % MOD * inv(2, MOD) % MOD) % MOD;

        cur = (cur + t2) % MOD;

        if (cnt[i] >= 5)
            cur = (cur + t1) % MOD;
        if (cnt[i + 1] >= 5)
            cur = (cur + t1) % MOD;

        if (cnt[i] >= 7)
            cur = (cur + 1) % MOD;
        if (cnt[i + 1] >= 7)
            cur = (cur + 1) % MOD;

        if (cnt[i] >= 5 && cnt[i + 1] >= 5)
            cur = (cur + 1) % MOD;

        ans = (ans + cur) % MOD;
    }

    cout << ans << endl;
}

E,F – 小红出牌

算法:

    贪心。

思路:

    先考虑没有前 \(x\) 张牌的概念,考虑对于整个数组其顺子个数为多少。

    假设有连续的三个元素出现次数为 \(1, 3, 2\),顺子个数为 \(3\) 个,如果第三个元素为 \(4\),那么顺子个数为 \(4\) 个,不难发现数字 \(i\) 对答案的影响为 \(max(0, cnt[i] – cnt[i – 1])\)。

    考虑 \(x\),定义 \(cnt\) 数组存储当前每个元素的出现次数,对于当前要添加的数字 \(a[i]\) 发现其只影响 \(cnt[a[i]], cnt[a[i] – 1], cnt[a[i] + 1]\),那么只需再添加数字前减去其影响,将其个数增加后再添加上其影响即可。

关键代码:

void miyan()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; ++i)
        cin >> a[i];

    vector<int> b(n + 1, 0);

    int ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        ans -= max(0, b[a[i]] - b[a[i] - 1]);
        ans -= max(0, b[a[i] + 1] - b[a[i]]);

        ++b[a[i]];

        ans += max(0, b[a[i]] - b[a[i] - 1]);
        ans += max(0, b[a[i] + 1] - b[a[i]]);

        cout << ans << ' ';
    }

    cout << endl;
}

G – 小红出千

算法:

    树状数组。

思路:

    最优解是滑动窗口。

    考虑将 \(a[i]\) 设为顺子的开头,计算数组需要变换多少元素可以变为长度为 \(n\) 且连续的顺子。

    对于计算部分,可以使用树状数组 + 离散化快速计算。

    计算出最小次数与最小开头后,将没用的元素修改掉即可。

关键代码:

struct BIT
{
    int n;
    vector<ll> tr;
    BIT(int _N)
    {
        n = _N;
        tr.resize(n + 1, 0);
    }

    int lowbit(int x) { return x & -x; }

    void add(int x, ll v)
    {
        for (int i = x; i <= n; i += lowbit(i))
            tr[i] += v;
    }

    ll query(int l, int r)
    {
        auto ask = [&](int x)
        {
            ll ans = 0;
            for (int i = x; i; i -= lowbit(i))
                ans += tr[i];
            return ans;
        };
        return ask(r) - ask(l - 1);
    }
};

void miyan()
{
    int n;
    cin >> n;
    vector<int> a(n);
    for (auto &x : a)
        cin >> x;

    auto aa = a;
    auto b = a;
    for (auto x : a)
        b.push_back(x + n - 1);

    ranges::sort(b);
    b.erase(unique(all(b)), b.end());

    for (auto &x : a)
        x = ranges::lower_bound(b, x) - b.begin() + 1;

    BIT bit(N);

    for (int i = 0; i < n; ++i)
    {
        if (!bit.query(a[i], a[i]))
            bit.add(a[i], 1);
    }

    int ans = INT_MAX;
    int val = 0;
    for (int i = 0; i < n; ++i)
    {
        int R = ranges::lower_bound(b, aa[i] + n - 1) - b.begin() + 1;

        int cur = n - bit.query(a[i], R);

        if (cur < ans)
        {
            ans = cur;
            val = aa[i];
        }
    }

    cout << ans << endl;

    map<int, int> st;
    for (int i = 0; i < n; ++i)
        ++st[aa[i]];

    set<int> S;

    int L = val, R = val + n - 1;
    vector<int> res;
    for (int i = 0; i < n; ++i)
    {
        if (aa[i] >= L && aa[i] <= R && !S.count(aa[i]))
            S.insert(aa[i]);
        else
            res.push_back(i + 1);
    }

    for (int i = L; i <= R; ++i)
    {
        if (!st[i])
        {
            cout << res.back() << ' ' << i << endl;
            res.pop_back();
        }
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇