D、Happy New Year!

签到题,暴力即可。

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define all(__vv__) (__vv__).begin(), (__vv__).end()
#define endl "\n"
#define pai pair<int, int>
#define ms(__x__,__val__) memset(__x__, __val__, sizeof(__x__))
#define rep(i, sta, en) for(int i=sta; i<=en; ++i)
#define repp(i, sta, en) for(int i=sta; i>=en; --i)
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar())    s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; }
inline void print(ll x, int op = 10) { if (!x) { putchar('0'); if (op)    putchar(op); return; }    char F[40]; ll tmp = x > 0 ? x : -x;    if (x < 0)putchar('-');    int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';        tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]);    if (op)    putchar(op); }
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll qpow(ll a, ll b) { ll ans = 1;    while (b) { if (b & 1)    ans *= a;        b >>= 1;        a *= a; }    return ans; }    ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; }
const int dir[][2] = { {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 7;

ll n, m;
ll a[N];

int calc(int x) {
    int cnt = 0;
    while (x) {
        cnt = cnt + (x % 10);
        x /= 10;
    }
    return cnt;
}

void solve() {
    n = read();
    m = calc(n);
    while (true) {
        ++n;
        ll tmp = calc(n);
        if (tmp == m) {
            print(n);
            break;
        }
    }
}

int main() {
    //int T = read();    while (T--)
    solve();
    return 0;
}

G、糖果

给出朋友关系,并且保证每个朋友之间糖果数目要相同。并查集维护一下连通块大小,以及连通块里面的最大值。

const int N = 1e6 + 7;

ll n, m;
ll fa[N], sz[N], a[N];
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
void merge(int u, int v) {
    int fu = find(u), fv = find(v);
    if (fu != fv) {
        fa[fv] = fu;
        sz[fu] += sz[fv];
        a[fu] = a[fv] = max(a[fu], a[fv]);
    }
}

void solve() {
    n = read(), m = read();
    rep(i, 1, n)    a[i] = read(), fa[i] = i, sz[i] = 1;
    while (m--) {
        int u = read(), v = read();
        merge(u, v);
    }
    ll ans = 0;
    rep(i, 1, n)
        if (fa[i] == i) ans += sz[i] * a[i];
    print(ans);
}

J、加法和乘法

将n先分奇偶讨论,当n是奇数的时候一定是牛妹进行最后一次操作。那么无论最后剩下来是奇奇,奇偶,偶偶的情况,牛妹一定可以把他们整合成偶数。注意特判一下n=1的情况。
那么当n是偶数的时候,牛牛是做最后一次。那么牛牛最终要合成一个奇数,牛妹如果不想让它赢就提前把全部可能的奇数合成偶数就行了。那么我们知道在牛牛动手游戏结束前,牛妹可以动次。那就看一下牛妹能不能把这里面的奇数全部变成偶数就行了。统计一下奇数卡牌的数量,牛妹每次可以消耗两张奇数牌。

const int N = 1e6 + 7;

ll n, m;
ll a[N];
void solve() {
    n = read();
    int cnt = 0;
    rep(i, 1, n) {
        a[i] = read();
        if (a[i] & 1)    ++cnt;
    }
    if (n == 1) {
        if (cnt)    puts("NiuNiu");
        else puts("NiuMei");
    }
    else if (n & 1)    puts("NiuMei");
    else {
        if ((n / 2 - 1) * 2 < cnt)    puts("NiuNiu");
        else puts("NiuMei");
    }
}

H、数字串

模拟。先从头到尾判断一下,有没有可以替换的点,如果不存在可以替换的地方说明无解。
那么什么是可替换的点如果原串中存在。并且注意后面可接到。但是后面只能到
又或者存在,这样的可以扩大的位置。但是注意不存在0,要跳过10,20这样权值的字母。

const int N = 1e6 + 7;

ll n, m;
char s[N];

bool check(int i) {
    if (s[i] == 'a' and s[i + 1] <= 'a' + 8)    return 1;
    if (s[i] == 'b' and s[i + 1] <= 'a' + 5)    return 1;
    return 0;
}

void solve() {
    scanf("%s", s + 1);
    bool flag = 0;
    n = strlen(s + 1);
    rep(i, 1, n) {
        int tmp = s[i] - 'a' + 1;
        if (tmp >= 11 and tmp != 20)    flag = 1;
        if (i == n)    continue;
        if (check(i))    flag = 1;
    }
    if (!flag) { puts("-1"); return; }
    rep(i, 1, n) {
        int tmp = s[i] - 'a' + 1;
        if (i != n and check(i)) {
            int tmp = s[i] - 'a' + 1;
            tmp *= 10; tmp += s[i + 1] - 'a' + 1;
            putchar('a' + tmp - 1);
            ++i;
        }
        else if (tmp <= 10 or tmp == 20)    putchar(s[i]);
        else {
            int a = tmp / 10, b = tmp % 10;
            putchar('a' + a - 1);
            putchar('a' + b - 1);
        }
    }
}

I、序列的美观度

动态规划,使用代表从1到的合理答案是多少。转移方程是:
如果这个元素前面出现过,那么就在它之前出现的位置值加一。

const int N = 1e6 + 7;

ll n, m;
ll a[N], dp[N];
void solve() {
    n = read();
    rep(i, 1, n)    a[i] = read();
    unordered_map<int, int> mp;
    rep(i, 1, n) {
        dp[i] = dp[i - 1];
        if (mp.count(a[i])) dp[i] = max(dp[i], dp[mp[a[i]]] + 1);
        mp[a[i]] = i;
    }
    print(dp[n]);
}

F、匹配串

字符串模拟。把井号看出正则表达式里面的匹配的话,那这个题目就会更好理解。
第一步首先我们看有没有出现不带号的匹配串,如果出现了说明下面我们就要围绕这个匹配串去找,如果没出现我们的判断规则就要另外找。