2025CCPC河北省赛题解

题目区分度不错,不过两题手快铜确实没想到。
Attention is all you need!

H - What is all you need?

签到题

#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long double

using namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
string s;
void solve()
{
    cin >> s;
    string u = s.substr(s.size() - 12);
    if (u == "isallyouneed")
    {
        cout << "Yes\n";
        cout << s.substr(0, s.size() - 12) << "\n";
    }
    else
        cout << "No\n";
}

signed main()
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}
M - 第九届河北省大学生程序设计竞赛

dfs搜索即可。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long double

using namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
int n, m, ra, rb, rc, pa, pb, pc, f;
vector<int> q;
string s[210];

void dfs(int u)
{
    if (f)
        return;
    if (u == n)
    {
        if (q.size() >= 10 && q.size() <= 13)
        {
            vector<int> su;
            for (int i = 1; i <= m; i++)
            {
                int sum = 0;
                for (int j = 0; j < q.size(); j++)
                    if (s[i][q[j]] == '1')
                        sum++;
                su.push_back(sum);
            }
            sort(su.begin(), su.end(), greater());
            if (su[ra - 1] == pa && su[rb - 1] == pb && su[rc - 1] == pc)
            {
                f = 1;
                cout << q.size() << "\n";
                for (int i = 0; i < q.size(); i++)
                    cout << q[i] + 1 << " ";
            }
        }
        return;
    }

    dfs(u + 1);
    q.push_back(u);
    dfs(u + 1);
    q.pop_back();
}
void solve()
{
    cin >> n >> m;
    for (int i = 1; i <= m; i++)
        cin >> s[i];
    cin >> ra >> rb >> rc >> pa >> pb >> pc;

    dfs(0);
    if (!f)
        cout << "-1";
}

signed main()
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}
J - Generate 01 String

模拟。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long double

using namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
int sa, sb;
string s;
void solve()
{
    cin >> s;
    for (int i = 0; i < s.size(); i++)
        if (s[i] == '0')
            sa++;
        else
            sb++;
    if (sa != sb)
    {
        cout << "-1\n";
        return;
    }
    vector<PII> res;
    priority_queue<PII, vector<PII>, greater<PII>> h;
    h.push({0, 3});
    int op = 1;
    for (int i = 0; i < s.size(); i++)
    {
        int u = s[i] - '0';
        if (h.top().y == u)
            h.pop();
        else
        {
            if (h.top().y == 3)
            {
                auto t = h.top();
                h.pop();
                if (h.size() && h.top().y == u)
                {
                    h.pop();
                    op++;
                }
                else
                {
                    if (u == 0)
                    {
                        res.push_back({op, 1});
                        h.push({t.x, 3});
                        h.push({t.x - 1, 1});
                        h.push({t.x - 2, 3});
                    }
                    else
                    {
                        res.push_back({op, 2});
                        h.push({t.x, 3});
                        h.push({t.x - 1, 0});
                        h.push({t.x - 2, 3});
                    }
                }
            }
            else
            {
                cout << "-1\n";
                return;
            }
        }
    }

    cout << res.size() << "\n";
    for (int i = 0; i < res.size(); i++)
        cout << res[i].x << " " << res[i].y << "\n";
}

signed main()
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}
K - UNO!

还是模拟,可以用链表,图省事可以用数组模拟链表。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long double

using namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
string s;
void solve()
{
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    vector<int> next(n);
    iota(next.begin(), next.end(), 1);
    next[n - 1] = 0;
    vector<int> pre(n);
    iota(pre.begin(), pre.end(), -1);
    pre[0] = n - 1;
    string op;
    cin >> op;
    int cur = 0, v = 1;

    for (int i = 0; i < m; ++i)
    {
        if (op[i] == 'C')
        {
            a[cur]--;
            if (a[cur] == 0)
            {
                pre[next[cur]] = pre[cur];
                next[pre[cur]] = next[cur];
            }
            if (v)
            {
                cur = next[cur];
            }
            else
            {
                cur = pre[cur];
            }
        }
        else if (op[i] == 'S')
        {
            a[cur]--;
            if (a[cur] == 0)
            {
                pre[next[cur]] = pre[cur];
                next[pre[cur]] = next[cur];
            }
            if (v)
            {
                cur = next[next[cur]];
            }
            else
            {
                cur = pre[pre[cur]];
            }
        }
        else if (op[i] == 'R')
        {
            a[cur]--;
            if (a[cur] == 0)
            {
                pre[next[cur]] = pre[cur];
                next[pre[cur]] = next[cur];
            }
            if (v == 1)
            {
                v = 0;
                cur = pre[cur];
            }
            else
            {
                v = 1;
                cur = next[cur];
            }
        }
        else if (op[i] == 'D')
        {
            a[cur]--;
            if (a[cur] == 0)
            {
                pre[next[cur]] = pre[cur];
                next[pre[cur]] = next[cur];
            }
            if (v)
            {
                cur = next[cur];
                a[cur] += 2;
                cur = next[cur];
            }
            else
            {
                cur = pre[cur];
                a[cur] += 2;
                cur = pre[cur];
            }
        }
    }
    for (int i = 0; i < n; ++i)
    {
        cout << a[i] << '\n';
    }
}

signed main()
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}
A - 棋盘

分类讨论,好像分太多了。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long double

using namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
string s;
void solve()
{
    int n;
    cin >> n;
    vector<int> a(n), b(n);
    int alla = 0;
    int allb = 0;
    for (int i = 0; i < n; ++i)
    {
        cin >> a[i];
        alla += a[i];
    }
    for (int i = 0; i < n; ++i)
    {
        cin >> b[i];
        allb += b[i];
    }
    vector<int> prefix(n), suffix(n);
    for (int i = 0; i < n; ++i)
    {
        if (i == 0)
            prefix[i] = a[0] + b[0];
        else
        {
            prefix[i] = prefix[i - 1] + a[i] + b[i];
        }
    }
    for (int i = n - 1; i >= 0; --i)
    {
        if (i == n - 1)
            suffix[i] = a[i] + b[i];
        else
        {
            suffix[i] = suffix[i + 1] + a[i] + b[i];
        }
    }
    // 3
    // 1
    // 3
    // 2
    // 3
    // 1 2 3
    // 3 2 1
    // 10
    // 3 2 1 3 3 2 3 9 4 2
    // 1 3 1 1 4 3 9 3 4 1
    int all = alla + allb;

    int l, r;
    for (int i = 0; i < n; ++i)
    {
        if (prefix[i] * 2 > all)
        {
            l = i;
            break;
        }
    }
    for (int i = n - 1; i >= 0; --i)
    {
        if (suffix[i] * 2 > all)
        {
            r = i;
            break;
        }
    }
    int disl = l, disr = n - r - 1;
    // cout << disl << ' ' << disr << endl;
    if (l == r)
    {
        if (disl == disr)
        {
            if (alla > allb)
            {
                cout << "Mandy\n";
            }
            else if (alla == allb)
            {
                cout << "draw\n";
            }
            else
            {
                cout << "brz\n";
            }
        }
        else if (disl < disr)
        {
            cout << "Mandy\n";
        }
        else
        {
            if (disl - 1 == disr)
            {
                if (alla > allb)
                {
                    cout << "Mandy\n";
                }
                else if (alla == allb || prefix[l - 1] * 2 == all)
                {
                    cout << "draw\n";
                }
                else
                {
                    cout << "brz\n";
                }
            }
            else
            {
                cout << "brz\n";
            }
        }
    }
    else
    {
        if (disl == disr)
        {
            if (alla > allb)
            {
                cout << "Mandy\n";
            }
            else if (alla == allb || prefix[l - 1] * 2 == all)
            {
                cout << "draw\n";
            }
            else
            {
                cout << "brz\n";
            }
        }
        else if (disl < disr)
        {
            if (disl + 1 == disr)
            {
                if (alla > allb)
                {
                    cout << "Mandy\n";
                }
                else if (alla == allb || prefix[l - 1] * 2 == all)
                {
                    cout << "draw\n";
                }
                else
                {
                    cout << "brz\n";
                }
            }
            else
            {
                cout << "Mandy\n";
            }
        }
        else
        {
            if (disl == disr + 1 || disl == disr + 2)
            {
                if (allb > alla)
                {
                    cout << "brz\n";
                }
                else if (alla == allb || suffix[r + 1] * 2 == all)
                {
                    cout << "draw\n";
                }
                else
                {
                    cout << "Mandy\n";
                }
            }
            else
            {
                cout << "brz\n";
            }
        }
    }
}

signed main()
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
        solve();
    return 0;
}
D - 金麦园

这道题比较有意思,首先简化题意,让你求第K大,你会求嘛?
对的,二分就可以了。现在让我们求前K个的和呢?
其实一样的,先排序求出第K大,再计算每个相邻差值的贡献,用到了双指针,二分+二分会TLE,所以优化成双指针。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long double

using namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int N = 1000010, M = N * 2, mod = 998244353, P = 131;
int n, k;
int a[N], s[N], mp[N];

int check(int x)
{
    int sum = 0;
    for (int i = 1, j = 1; i <= n; i++)
    {
        while (j + 1 <= n && a[j + 1] - a[i] < x)
            j++;
        sum += j - i;
    }
    return sum;
}
void solve()
{
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    sort(a + 1, a + n + 1);

    int l = 0, r = 1e9;
    while (l < r)
    {
        int mid = (l + r + 1) / 2;
        if (check(mid) < k)
            l = mid;
        else
            r = mid - 1;
    }
    int cnt = 0, res = 0;
    for (int i = 1, j = 1; i <= n; i++)
    {
        while (j + 1 <= n && a[j + 1] - a[i] < l)
            j++;
        cnt += j - i;
        // cout << i << " " << j << "\n";
        mp[i + 1] = j - i;
        s[i + 1]++, s[j + 1]--;
    }
    for (int i = 1; i <= n; i++)
        s[i] += s[i - 1];
    for (int i = 2; i <= n; i++)
    {
        if (mp[i])
        {
            res += mp[i] * (a[i] - a[i - 1]);
            if (mp[i] - s[i])
            {
                mp[i + 1] += mp[i] - s[i];
            }
        }
    }
    if (cnt < k)
        res += (k - cnt) * l;
    cout << res << "\n";
}

signed main()
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}
I - 感染

换根DP。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
#define double long double

using namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
// const int N = 1000010, M = N * 2, mod = 998244353, P = 131;

void solve()
{
    int n;
    cin >> n;
    vector<vector<int>> adj(n);
    vector<int> d(n);
    for (int i = 1; i < n; i++)
    {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        adj[u].push_back(v);
        adj[v].push_back(u);
        d[u]++;
        d[v]++;
    }
    vector<int> sumd(n), dep(n);
    // int maxdep = 0;
    auto dfs = [&](auto &&self, int x, int p = -1) -> void
    {
        sumd[x] = d[x];
        for (auto y : adj[x])
        {
            if (y == p)
            {
                continue;
            }
            dep[y] = dep[x] + 1;
            // maxdep = max(maxdep, dep[y]);
            self(self, y, x);
            sumd[x] += sumd[y];
        }
    };
    // int m = maxdep + 1;
    dfs(dfs, 0);
    vector<int> dp(n);
    dp[0] = 1;
    for (int i = 0; i < n; i++)
    {
        dp[0] += d[i] * (n + 1 - dep[i]);
    }
    // cout << sumd[0] << "\n";
    auto dfs2 = [&](auto &&self, int x, int p = -1) -> void
    {
        for (auto y : adj[x])
        {
            if (y == p)
            {
                continue;
            }
            dp[y] = dp[x] + 2 * sumd[y] - sumd[0];
            // cout << "!!!\n";
            // cout << "sumd " << sumd[y] << "\n";
            // cout << y << " " << dp[y] << "\n";
            self(self, y, x);
        }
    };
    dfs2(dfs2, 0);

    // for (int i = 0; i < n; i++)
    // {
    //     cout << dp[i] << "\n";
    // }

    int maxv = *std::max_element(dp.begin(), dp.end());
    vector<int> vec;
    for (int i = 0; i < n; i++)
    {
        if (dp[i] == maxv)
        {
            vec.push_back(i + 1);
        }
    }
    cout << vec.size() << "\n";
    for (auto x : vec)
    {
        cout << x << " \n"[x == vec.back()];
    }
}

signed main()
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
        solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安特尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值