Codeforces Global Round 29 (Div. 1 + Div. 2)

链接:https://codeforces.com/contest/2147

A. Shortest Increasing Path

算法:

    找规律。

思路:

    答案只有 \(-1\) \(2\) \(3\) 三种情况。

  • \(x < y\):两步即可。
  • \(x == y\):不成立。
  • \(x > y\) 时
    • \(y == 1\): 不成立。
    • \(x >= y + 2\):可以选出来,需要三步。

关键代码:

void miyan()
{
    ll x, y;
    cin >> x >> y;

    if (x < y)
        cout << 2 << endl;
    else if (x == y)
        cout << -1 << endl;
    else
    {
        if (y == 1)
            cout << -1 << endl;
        else if (x >= y + 2)
            cout << 3 << endl;
        else
            cout << -1 << endl;
    }
}

B. Multiple Construction

算法:

    构造。

思路:

    手玩几组样例。

关键代码:

void miyan()
{
    int n;
    cin >> n;

    for (int i = n; i; --i)
        cout << i << ' ';
    cout << n << ' ';
    for (int i = 1; i < n; ++i)
        cout << i << ' ';
    cout << endl;
}

C. Rabbits

算法:

    贪心,模拟,找规律。

思路:

    可以发现以下几条规律:

  • 相邻的两个 \(1\) 可以被完全分割成两段并且完全不受对方影响。
  • 被规则 \(1\) 分割后的字符串中存在相邻 \(0\) 的子串必然成立,此时也可以将相邻的 \(0\) 进行分割成两段。
  • 如果某一段的第一个字符为 \(0\) 并且为开头或者最后一个字符为 \(0\) 并且为结尾,那么这一段必然成立。

    最后对于由规则 \(1\) \(2\) 分割后的段必然为 \(0\) \(1\) 交替段,可以发现只有当左右端点都为 \(1\) 的段才可能不成立。

    因为如果有一个端点为 \(0\) ,那么他可能为:

  • 起点或者终点,由规则 \(3\) 可知必然成立。
  • 被规则 \(2\) 分割而来,也必然成立。

关键代码:

void miyan()
{
    int n;
    string s;
    cin >> n >> s;

    bool flag = (s[0] == '0');
    ll cnt = (s[0] == '0');
    for (int i = 0; i < n; ++i)
    {
        if (s[i] == '0')
            ++cnt;

        if (s[i] == s[i - 1])
        {
            if (s[i] - '0')
            {
                if (!flag && cnt % 2 == 1)
                {
                    cout << "NO" << endl;
                    return;
                }

                flag = 0;
                cnt = 0;
            }
            else
                flag = 1;
        }
    }

    if (!flag && cnt % 2 == 1 && s[n - 1] - '0')
    {
        cout << "NO" << endl;
        return;
    }

    cout << "YES" << endl;
}

D. Game on Array

算法:

    博弈论,贪心。

思路:

    这题的主要难点在于想到对奇偶的不同决策。

    对于偶数,每个人的最优策略必然都是每个人都拿走一半,既一个偶数,先手先取了,后手也可以跟着取,所有偶数会均分给双方。

    对于奇数,一个人取完之后,其就变为了偶数,后续的最优策略与偶数情况相同。

    所有双方的最优策略就为抢出现次数最多的奇数。

    使用一个桶存储每个奇数出现的次数,使用大根堆模拟双方选择的操作即可。

关键代码:

void miyan()
{
    int n;
    cin >> n;

    ll ans1 = 0, ans2 = 0;
    map<int, int> m;
    while (n--)
    {
        int x;
        cin >> x;
        if (x & 1)
            ++m[x];
        ans1 += x / 2, ans2 += x / 2;
    }

    priority_queue<int> q;
    for (auto [_, x] : m)
        q.push(x);

    ll now = 1;
    while (q.size())
    {
        if (now)
            ans1 += q.top(), q.pop();
        else
            ans2 += q.top(), q.pop();

        now = !now;
    }

    cout << ans1 << ' ' << ans2 << endl;
}

E. Maximum OR Popcount

    还没补。

暂无评论

发送评论 编辑评论


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