参考代码放在最后面。

思路

A.小红的双层夹心

按照题意直接比较即可。


B.小红的马卡龙定位

中点公式

可以逐一枚举,也可以移项偷懒,减少代码量


C.小红的奶油蛋糕工坊

通过定义,我们容易得到:修改值连续的 个数字并改成中位数一定不劣。

证明:

由于给出序列是排列,所以每种数只有一个,那么需要修改 个数字。

设相等的数字为 ,则其余数字 改成 所需代价为 ,由函数性质可知,最小的值一定在 的两侧,即连续的数字。

一种便于实现的做法就是将 的数字改成其中位数(如果存在两个任取一个即可。)

时间复杂度为


D.小红的奇数奶油球

我们倾定 为根,那么我们可以 DFS 求出对应节点的子树大小

按照题目定义,一个节点是好的,满足删除 节点后一定满足其子节点 大小都是奇数,此时还剩下父亲节点与节点 形成的子树,其大小为 ,判断一下即可。

时间复杂度为


E.小红的提拉米苏配方(easy)

由于所有的 1 都要操作到无法操作为止,所以最后只会剩余 1,于是可以进行分类讨论。

  • 1 的个数是偶数:由于 2 的字典序最大,所以可以贪心将所有的 2 全部放到最后面,即变成 21 一定是后者,结果一定不劣。
  • 1 的个数是奇数:由于存在其中一个 1 不需要被删除,于是我们选择尽可能靠前的 12 结构中的 1 进行保留,若不存在则保留尽可能后的 1(但是要在所有变成 21 之前。)

感性理解一下:(下划线为被删除的 1,加粗为变成 21

这个过程跑左右端双指针即可完成。

时间复杂度为


F.小红的提拉米苏配方 (hard)

和 E 题类似,当存在 12 结构时,不删除一定最优,此时,拓展一下即可得到另一种情况下删除一定更优,即 10 的情况。

因此,我们可以将 1...10 尽可能删除成 0,若后续的 1 数量足够,如果不够就尽可能删。

于是我们可以预处理出每个位置后缀 1 的数量,然后同样跑双指针处理当前 1 组成的连通块 11...11x,然后分类讨论 1012 的情况,尽可能地删 10 的前导 1

时间复杂度为


代码(C++)

A.小红的双层夹心

void solve(){
    string s;
    cin >> s;
    cout << (s[1] == s[2] ? "Yes" : "No") << "\n";
}

B.小红的马卡龙定位

using p32 = std::array<int,2>;
void solve(){
    vector<p32> p(4);
    i64 sx=0,sy=0;
    for (int i = 1;i <= 3;i++){
        cin >> p[i][0] >> p[i][1];
        sx += p[i][0];
        sy += p[i][1];
    }
    for (int i = 1;i <= 3;i++){
        if (sx == p[i][0]*3 && sy == p[i][1]*3){
            cout << i << "\n";
            return;
        }
    }
}

C.小红的奶油蛋糕工坊

void solve(){
    int n;
    cin >> n;
    vector<int> a(n+1);
    for (int i = 1;i <= n;i++) cin >> a[i];
    int tp = (n+1) / 2,goal = (tp+1) / 2;
    for (int i = 1;i <= n;i++) {
        if (a[i] <= tp) a[i] = goal;
    }
    for (int i = 1;i <= n;i++) cout << a[i] << " \n"[i==n];
}

D.小红的奇数奶油球

void solve(){
    int n;
    cin >> n;
    vector<vector<int>> G(n+1);
    vector<int> size(n+1,1),fa(n+1);
    for (int i = 1;i < n;i++){
        int u,v;
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    auto dfs = [&](this auto&& self,int u,int pa)->void {
        fa[u] = pa;
        for (int v : G[u]){
            if (v == pa) continue;
            self(v,u);
            size[u] += size[v];
        }
    };
    dfs(1,1);
    int ans = 0;
    for (int u = 1;u <= n;u++){
        int add = 1;
        for (int v : G[u]){
            if (v == fa[u]){
                if ((n - size[u]) % 2 == 0) add = 0;
            } else {
                if (size[v] % 2 == 0) add = 0;
            }
        }
        ans += add;
    }
    cout << ans << "\n";
}

E.小红的提拉米苏配方(easy)

void solve(){
    string s;
    cin >> s;
    int n = s.size();
    vector<int> typ(n),vis(n,1);
    int cnt = 0;
    for (int i = n-1;i >= 0;i--){
        if (s[i] == '1') {
            cnt++;
        }
    }
    bool tag = cnt & 1;
    for (int l = 0,r = n-1;l < r;l++,r--){
        while (l < r && s[l] != '1') l++;
        if (tag && l < r && s[l] < s[l+1]){
            tag = 0,l++;
            while (l < r && s[l] != '1') l++;
        }
        while (l < r && s[r] != '1') r--;
        if (l == r) break;
        vis[l] = 0,vis[r] = 2;
    }
    for (int i = 0;i < n;i++){
        if (vis[i] == 1) cout << s[i];
        else if (vis[i] == 2) cout << '2';
    }
    cout << "\n";
}

F.小红的提拉米苏配方 (hard)

void solve(){
    string s;
    cin >> s;
    int n = s.size();
    vector<int> vis(n,1),suf(n);
    for (int i = n-1;i >= 0;i--){
        if (i != n-1) suf[i] = suf[i+1];
        if (s[i] == '1') {
            suf[i]++;
        }
    }
    int mid = 0,cnt = 0;
    for (int l = 0,r = 0;r < n;r++){
        if (s[r] != '1') continue;
        while (r < n && s[r] == '1'){
            r++;
        }
        if (r >= n || s[r] == '2') continue;
        l = r-1;
        while (l >= 0 && r < n && s[l] == '1' && cnt + 1 <= suf[r]){
            cnt++;
            vis[l] = 0;
            l--;
        }
    }
    for (int i = n-1;i >= 0;i--){
        if (s[i] == '1' && cnt > 0){
            cnt--;
            vis[i] = 2;
        }
    }
    for (int i = 0;i < n;i++){
        if (vis[i] == 1) cout << s[i];
        else if (vis[i] == 2) cout << '2';
    }
    cout << "\n";
}

头文件(模板)

#include<bits/stdc++.h>
#if __has_include("tool/local.hpp")
#include "tool/local.hpp"
#include "grader.hpp"
#else
#define Testcases(T) while(T--) solve();
    #ifndef ONLINE_JUDGE
    #define listen(...) freopen("data.in","r",stdin),freopen("data.out","w",stdout);
    #else
    #define listen(...)
    #endif
#endif
using namespace std;
// Base type
using ll = long long;
using ld = long double;
using i64 = long long;
using f128 = long double;
using u64 = unsigned long long;
using p32 = std::array<int,2>;
using p64 = std::array<i64,2>;

// mt19937_64 rnd(time(0));

void solve(){
}

signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr),std::cout.tie(nullptr);
    listen(_TIMER,_FILE,_CHECKER);
    int T = 1;
    // std::cin >> T;
    Testcases(T);
    return 0;
}

End

复建了一下,唐完了。