Codeforces Round #778 (Div. 1 + Div. 2, based on Technocup 2022 Final Round) (A-C题解)

源代码:ACM/OpenjudgeNow/Codeforces at master · abmcar/ACM (github.com)

更好的阅读体验: Codeforces Round #778 (Div. 1 + Div. 2, based on Technocup 2022 Final Round) (A-C题解) - Abmcar’s 茶水间

A. Maximum Cake Tastiness

题目大意:

image-20220325205920708

思路:

可以证明通过旋转可以使得最大的蛋糕和次大的蛋糕相邻

因此最大美味为最大+次大

代码:
void solution()
{
    int maxn1, maxn2;
    maxn1 = maxn2 = 0;
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i < n; i++)
        cin >> nums[i];
    sort(nums.begin(), nums.end(), greater<int>());
    cout << nums[0] + nums[1] << endl;
}

B. Prefix Removals

题目大意:

image-20220323110254001

思路:

B题的题目非常具有迷惑性,一直让找最长的前缀

但我们可以发现,对于任意最长前缀 p r e f i x 0 = p r e f i x 1 + p r e f i x 2 prefix_0=prefix1+prefix2 prefix0=prefix1+prefix2

如果先处理掉 p r e f i x 1 prefix1 prefix1再处理 p r e f i x 2 prefix2 prefix2和直接处理 p r e f i x 0 prefix0 prefix0没有区别

由此逐步处理,单个字母单个字母地处理对最后结果同样没有影响

所以如果我们找到一个字母,在它之后的字符串中该字母没有出现过,则停止

我们可以记录下当前位置前每个字母的个数,若当前位置该字母个数等于整个字符串中该字母个数,则停止

剩下部分即为最终字符串

代码:
void solution()
{
    map<char, int> M, M1;
    string ori;
    cin >> ori;
    for (char it : ori)
        M[it]++;
    int cnt = 0;
    for (int i = 0; i < ori.size(); i++)
    {
        M1[ori[i]]++;
        if (M1[ori[i]] == M[ori[i]])
        {
            cnt = i;
            break;
        }
    }
    for (int i = cnt; i < ori.size(); i++)
        cout << ori[i];
    cout << endl;
}

C. Alice and the Cake

题目大意:

image-20220325210555752

思路:

发现 ⌊ w 2 ⌋ + ⌈ w 2 ⌉ = w \lfloor\frac{w}2\rfloor+\lceil\frac w 2\rceil = w 2w+2w=w

同时也发现,如果按照贪心的思路每次取某几个相加会有后效性,因此无法贪心

正难则反,我们可以从w出发取dfs判断是否可以分成某个数

同时,如果dfs到最后还没有在数组里出现,则直接可以判为NO,因为此时其余数之和已经不可能等于w了

代码:
int t, n;
map<int, int> M;
bool ok;
void solution()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin >> n;
    queue<int> Q;
    M.clear();
    int tot = 0;
    int cnt = 0;
    ok = true;
    for (int i = 1; i <= n; i++)
    {
        int tmp;
        cin >> tmp;
        tot += tmp;
        M[tmp]++;
    }
    function<void(int)> dfs = [&](int nowNum) -> void {
        if (!ok)
            return;
        if (M[nowNum])
        {
            M[nowNum]--;
            return;
        }
        if (nowNum >= 2)
        {
            dfs(nowNum / 2);
            dfs((nowNum + 1) / 2);
        }
        else
            ok = false;
    };
    dfs(tot);
    for (auto it : M)
        if (it.second)
            ok = false;
    if (ok)
        cout << "YES" << endl;
    else
        cout << "NO" << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Abmcar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值