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

更好的阅读体验: Codeforces Round #776 (Div. 3) (A-E题解) - 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题的题目非常具有迷惑性,一直让找最长的前缀

但我们可以发现,对于任意最长前缀$prefix_0=prefix1+prefix2$

如果先处理掉$prefix1$再处理$prefix2$和直接处理$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

思路:

发现$\lfloor\frac2\rfloor+\lceil\frac w 2\rceil = 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;
}