07_04_暑期个人赛1

C. Canine poetry

时间:2024-07-05

原题:Good Bye 2020 C. Canine poetry

题意

对于一个字符串 \(s\) ,可以对任一字符变为 \(*\) 号,使所有子串不为回文串,即可将 \(babba\) 变为 \(ba*ba\) 使字符串内不存在回文串

数据范围: \(|s|\le 1e5\)

思路

对于某回文字符串,如果是长度为奇数,那么中心的三个字符组成的子串一定是字符串,偶数同理

那么将所有的长度为2和3的回文串进行处理就能达到效果

代码

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
#define int long long

int _, n;
vector<bool>vis;
void solve() {
    string s;
    cin >> s;
    int len = s.length();
    vis.assign(len, false);

    int ans = 0;
    for (int i = 1; i < s.length(); i++) {
        // 长度为2的回文串,如果没被换过,换后面的字符
        if (s[i] == s[i - 1] && !vis[i - 1]) {
            vis[i] = true;
            ans++;
        }
        // 长度为3的回文串,同理换第一个
        else if (i - 2 >= 0 && s[i] == s[i - 2] && !vis[i - 2]) {
            vis[i] = true;
            ans++;
        }
    }
    cout << ans << endl;
}
signed main() {
    cin >> _;
    while (_--)
        solve();
    return 0;
}

C. Ehab and Path-etic MEXs

时间:2024-07-05

原题:Codeforces Round 628 (Div. 2) C. Ehab and Path-etic MEXs

题意

有一颗 \(n\) 个结点的树,对每条边编号,属于 \([0,n-2]\) ,要求所有对节点对 \((u,v)\) ,其 \(MEX(u,v)\) 的最大值最小

\(MEX(u,v)\) 表示从 \(u\)\(v\) 的唯一简单路径上没出现过的最小编号

理解: 有点绕,就是说,有从 \(u\)\(v\) 假如经过了边1,2,4那么最小的未出现的数就是0,则 \(MEX(u,v)=0\)

\(Ans=max(MEX(u,v))\) ,求 \(Ans_{min}\)

思路

首先假定是最简单的情况,也就是一条链,那么简单看一下所有的可能性,可知 \(Ans=n-1\)

所以对于单链,随机存放即可

接下来,如果多了一条链,那么可以观察度大于等于3的点

对于这样的点,无论哪种 \((u,v)\) 的搭配,对于这个点至少有一条边不被覆盖

即只要将0,1,2这最小的三个编号分配在三条分路上,其他编号随意分配,就能实现 \(Ans=2\)

代码

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

#define int long long
#define rep(i,j,k) for(i=(j);i<(k);i++)
typedef pair<int, int> pii;
const int N = 1e5 + 10;

int n, ii;

vector<vector<int>>g;
int u[N], v[N];
void solve() {
    cin >> n;
    g.assign(n + 1, vector<int>(0));

    rep(ii, 0, n - 1) {
        cin >> u[ii] >> v[ii];
        g[u[ii]].emplace_back(v[ii]);
        g[v[ii]].emplace_back(u[ii]);
    }
    // 如果有大于等于3的度,以存储两个顶点的形式存储每条边,012对应共三条
    pii p[3];
    int i;
    for (i = 0; i < g.size(); i++) {
        vector<int> vv = g[i];
        if (vv.size() >= 3) {
            for (int j = 0; j < 3; j++) {
                p[j].first = i;
                p[j].second = vv[j];
            }
            break;
        }
    }
    // 如果没有大于等于3的度,随意输出
    if (i == g.size()) {
        rep(ii, 0, n - 1) {
            cout << ii << endl;
        }
        return;
    }

    
    int ans = 0;
    int index = 3;
    for (int i = 0; i < n - 1; i++) {
        int j;
        for (j = 0; j < 3; j++) {
            int f = p[j].first, s = p[j].second;
            // 如果是012所在的边,输出012,否则输出index
            if ((u[i] == f && v[i] == s) || (u[i] == s && v[i] == f)) {
                cout << ans << endl;
                ans++;
                break;
            }
        }
        if (j == 3) {
            cout << index++ << endl;
        }
    }
}
signed main() {
    solve();
    return 0;
}
posted @ 2024-07-05 23:14  lulaalu  阅读(10)  评论(0)    收藏  举报