跳转至

第十三届陕西省国际大学生程序设计竞赛 - 正式赛

2025-05-13

gym: https://codeforces.com/gym/105891

pEjewy4.png

打挺差的一集,VP只AC了四题。有一题卡很简单的地方了。虽然只VP三小时。回寝室又看了两小时。

A

显然每个颜色单独处理,然后就是看这次操作和上次操作隔着多少个距离,考虑是把中间的全部涂色还是开一次新的操作,哪个少选哪个就行。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve()
{
    int n;
    cin >> n;
    vector<int> c(n + 1), w(n + 1);
    vector<vector<int>> g(n + 1, vector<int>());
    for(int i = 1; i <= n; i++){
        cin >> c[i];
        g[c[i]].push_back(i);
    }
    for(int i = 1; i <= n; i++)
        cin >> w[i];
    for(int i = 1; i <= n; i++){
        // i = 2;
        g[i].push_back(n + 1);
        int res = 0, lst = -1, idx = 0;
        for(int j = 0; j < g[i].size(); j++){
            if(idx != g[i][j] - 1){
                if(lst == -1){
                    res += w[i] + (g[i][j] - idx - 1);
                }else{
                    res += min(w[i] + g[i][j] - idx - 1, g[i][j] - lst - 1);
                }
                lst = g[i][j] - 1;
            }
            idx = g[i][j];
            // cerr << idx <<" " << lst << " " << res << '\n';
        }
        cout << res << " \n" [i == n];
        // break;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int T = 1;
    // cin >> T;
    while(T--)
        solve();
    return 0;
}

C

一直把 \(b\)\(gcd(a, b)\) 直到 \(gcd(a, b) = 1\),因为这个东西你不除掉的话,\(a\)\(b\) 一定不互质,而且除了之后,一定是 \(b\) 的因子。

/*
gcd(a, b) = g
gcd(a / g, b / g) = 1

16 18

32 48
*/
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve()
{
    ll a, b;
    cin >> a >> b;
    if(b == 1)
        cout << "-1\n";
    else if(a == 1)
        cout << b << '\n'; 
    else{
        ll c = b;
        for(;c != 1;){
            ll g = gcd(a, c);
            if(g == 1) break;
            c /= g;
        }
        if(c == 1) c = -1;
        cout << c << '\n';
    }

}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int T;
    cin >> T;
    while(T--)
        solve();
    return 0;
}

G

很简单,证明简单,就是首先,\(a_1\)\(a_n\) 一定是删不掉的,中间的数字最多只能留下两个,最大值或者最小值。且若 \(a_1\)\(a_n\) 是最大值,则最大值也可以被删,若 \(a_1\)\(a_n\) 是最小值,则最小值也可以被删。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    if(n == 1){
        cout << "1\n";
        return;
    }
    int mx = *max_element(a.begin() + 1, a.end());
    int mn = *min_element(a.begin() + 1, a.end());
    if(a[1] < a[n]) swap(a[1], a[n]);
    if(a[1] == mx && a[n] == mn) cout << "2\n";
    else if(a[1] == mx || a[n] == mn) cout << "3\n";
    else cout << "4\n";
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int T = 1;
    // cin >> T;
    while(T--)
        solve();
    return 0;
}

J

由于四个字符都不同,只需要找到多的然后直接算就行。先凑长度长的。那我们就找能凑成 lose 的子序列的长度和数量就行,且不能重复,就先找长的就行。

糖丸了的地方是,长度为 \(3\) 的有四种,我们当时只写了三种,四个选三个显然是四种选法。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve()
{
    int k;
    cin >> k;

    string s;
    cin >> s;
    int n = s.size();

    vector<bool> vis(n);
    int cnt[5] {0, 0, 0, 0, 0 };

    for (int i = 0; i + 3 < n; i++) {
        if (vis[i] || vis[i + 1] || vis[i + 2] || vis[i + 3])
            continue;

        if (s.substr(i, 4) == "lose") {
            cnt[4]++;

            vis[i] =
            vis[i + 1] = 
            vis[i + 2] = 
            vis[i + 3] = true;
        }
    }

    // lose
    for (int i = 0; i + 2 < n; i++) {

        if (vis[i] || vis[i + 1] || vis[i + 2])
            continue;

        string t = s.substr(i, 3);

        if (t == "los" || t == "ose" || t == "lse" || t == "loe") {
            cnt[3]++;

            vis[i] = 
            vis[i + 1] = 
            vis[i + 2] = true;
        }
    }

    // lose
    for (int i = 0; i + 1 < n; i++) {

        if (vis[i] || vis[i + 1])
            continue;

        string t = s.substr(i, 2);

        if (t == "lo" || t == "ls" || t == "le" || t == "os" || t == "oe" || t == "se") {
            cnt[2]++;

            vis[i] = 
            vis[i + 1] = true;
        }
    }

    for (int i = 0; i < n; i++) {

        if (vis[i])
            continue;

        if (s[i] == 'l' || s[i] == 'o' || s[i] == 's' || s[i] == 'e') {
            cnt[1]++;

            vis[i] = true;
        }
    }

    // cout << cnt[4] <<" " << cnt[3] <<" " <<cnt[2] <<" " << cnt[1] << '\n';
    int ans = cnt[4];

    for (int i = 3; i >= 1; i--) {
        if (k >= cnt[i] * (4 - i)) {
            k -= cnt[i] * (4 - i);
            ans += cnt[i];
        } else {
            ans += k / (4 - i);
            k %= (4 - i);
            // break;
        }
    }
    ans += k / 4;
    cout << ans << '\n';
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int T = 1;
    // cin >> T;
    while (T--)
        solve();
    return 0;
}

K

挺简单,稍微讨论下就行。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve()
{
    ll n, m, x, y;
    cin >> n >> m >> x >> y;
    /*
    tangwanle
    现在才发现 无私的牛希望所有牛的草的总和最多
    本以为是他希望自己的同类得到的总和更多

    唉唉,太无私了
    但是这样是不是简单点来着

    如果自私牛全去 B, 那最好
    无私的牛最多派一个人去 A

    否则他可能得逼着大家去 B
    当然这些会和人数有关

    无私的牛肯定希望去 A 的牛会尽量少
    */
    //首先就看如果无私的都不去 A, 那么答案就是
    ll ans = 0;
    if(x > y){
        if(m)
            ans = max(ans, x + y * n);
        else if(n)
            ans = max(ans , x + (n - 1) * y);
        // 自私的全去 A, 无私的试试能不能让他们都不去 A

        // x / (1 + cnt) <= y
        // x <= y * cnt
        // cnt >= (x + y -1) / y, 它们才不会去
        if(y){
            int cnt = (x + y - 1) / y - 1;
            cnt = max(cnt, 1);
            if(n >= cnt)
                ans = max(ans, x + (m + n - cnt) * y);
        }
    }
    else{
        if(n)
            ans = max(ans, x + (m + n - 1) * y);
        ans = max(ans, (m + n) * y);
    }
    cout << ans << '\n';
}
int main()
{
    // freopen("1.in", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int T = 1;
    cin >> T;
    while (T--)
        solve();
    return 0;
}

L

签到题,随便选。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve()
{
    int n;
    cin >> n;
    ll ans = 0;
        for(int i = 1; i < n; i++){
            ans += 3 + (i - 1) * 2 * (n + 1);
        }
    ans += n * n + (n * n - n + 1);

    cout << ans << '\n';
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int T = 1;
    // cin >> T;
    while(T--)
        solve();
    return 0;
}