跳转至

2024北京航空航天大学程序设计竞赛 决赛

2025-05-08

link: https://codeforces.com/gym/105629

前几天打的,还没补题,先把写了的题给记一下吧。

由于是晚上打的,所以没有办法打满四小时,但是也差不多了感觉。

pEXnc1U.png

A

n = int(input())
print(n)

B

找到最小的可以满足的数字,然后比它大的都可以,比它小的都不行。求个区间和就行了。

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

constexpr int mod = 998244353;

ll ksm(ll a, ll b)
{
    ll res = 1;
    while(b){
        if(b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int x, y;
    cin >> x >> y;
    ll L = 0;
    for(int i = 1; i <= min(x - 1, y - 1); i++)
        L = (L * 10 + 4) % mod;
    L = (L * 10 + 5) % mod;
    for(int i = 1; i <= x - y; i++)
        L = L * 10 % mod;
    // cout << L << '\n';
    ll R = (ksm(10, x) - 1 + mod) % mod;
    ll ans = (L + R) * (R - L + 1) % mod * ksm(2, mod - 2) % mod;
    ans = (ans + mod) % mod;
    cout << ans << '\n';
    return 0;
}

C

过的人非常多的一道题,但是我们后面才想到。

\(n\) 为偶数的话,显然全负数就行。然后 \(n\) 为奇数,本以为不行的,在 WA 麻了之后突然发现,只需要整一个 \(2\) 就行,其他全 \(-1\)

for _ in range(int(input())):
    n = int(input())
    print("YES")
    if n & 1:
        for i in range(2 * n):
            print(-1, end = " ")
        print(2)
    else:
        for i in range(2 * n + 1):
            print(-1, end = " ")
        print()

D

也是签到题。

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

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int n, k;
    cin >> n >> k;
    vector<ll> a(k + 1), t(n + 1), c(n + 1);
    for(int i = 1; i <= k; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) cin >> t[i] >> c[i];
    // for(int i = 1; i <= n; i++) cin >> c[i];

    auto check = [&](int T){
        vector<ll> need(a);
        for(int i = 1; i <= T; i++){
            need[t[i]] -= c[i];
        }
        vector<ll> stk1, stk2;
        for(int i = 1; i <= k; i++){
            if(need[i] < 0) stk1.push_back(-need[i]);
            else if(need[i] > 0) stk2.push_back(need[i]);
        }
        while(stk1.size() && stk2.size()){
            auto x = stk1.back(), y = stk2.back();
            // cerr << x << " " << y << '\n';
            stk1.pop_back(), stk2.pop_back();
            if(3 * x > y){
                stk1.push_back(x - y / 3);
            }else{
                y -= 3 * x;
                if(y >= 3) stk2.push_back(y);
            }
        }
        return stk1.empty();
    };
    int lo = 0, hi = n + 1;
    while(lo < hi - 1){
        int mid = (lo + hi) >> 1;
        if(check(mid)) lo = mid;
        else hi = mid;
    }
    // cerr << check(5) << '\n';
    cout << lo << '\n';
    return 0;
}

E

感觉是这一场我们写出来的唯一稍微复杂点的题目。

题意是给一个有向图,每个节点有一种属性,我们需要对这个图,每次只能删除入度为 \(0\) 的点,如果删除了一种类型的点,就必须连着把这种类型的点删完。需要输出一种可行的顺序,若不行则输出 \(-1\)

那么这个过程很显然就是在进行拓扑排序,只是多了一点限制条件,需要记录一下就行,记录一下每种类型的点有没有其他类型的点连过来。感觉还是稍微有一点细节的,但难度不高。

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

void solve()
{
    int n, m;
    cin >> n >> m;
    vector<int> a(n + 1), cnt(n + 1), ru(n + 1);
    for(int i = 1; i <= n; i++) cin >> a[i];
    vector<vector<int>> g(n + 1, vector<int>());
    vector<vector<int>> g1(n + 1, vector<int>());
    // for(int i = 1; i <= n; i++)
    //     g1[a[i]].push_back(i);
    for(int i = 1; i <= m; i++){
        int x, y;
        cin >> x >> y;
        g[x].push_back(y);
        ru[y]++;
        if(a[x] != a[y]){
            cnt[a[y]]++;
        }
    }
    // queue<int> q;
    // vector<bool> vis(n + 1);
    // set<int> st;
    // auto cmp = [&](int x, int y){
    //     return a[x] < a[y];
    // };
    // priority_queue<int, vector<int>, decltype(cmp)>pq(cmp);
    set<int> color;
    vector<queue<int>>q(n + 1);
    {
        vector<int> tmp;
        for(int i = 1; i <= n; i++){
            // cerr << ru[i] << " " << cnt[a[i]] << '\n';

            if(ru[i] == 0 && cnt[a[i]] == 0){
                // q.push(i);
                // tmp.push_back(i);
                // pq.push(i);
                color.insert(a[i]);
            }
            if(ru[i] == 0)
                q[a[i]].push(i);
        }
        // sort(tmp.begin(), tmp.end(), [&](int x, int y){
        //     return a[x] < a[y];
        // });
        // for(auto x : tmp)
        //     q.push(x);
    }
    vector<int> ans;
    while(color.size()){
        int x = *color.begin();
        color.erase(color.begin());
        while(!q[x].empty()){
            int u = q[x].front();
            q[x].pop();
            ans.push_back(u);
            for(auto v : g[u]){
                ru[v]--;
                if(a[v] == x){
                    if(ru[v] == 0)
                        q[x].push(v);
                }else{
                    cnt[a[v]]--;
                    if(ru[v] == 0)
                        q[a[v]].push(v);
                    if(cnt[a[v]] == 0)
                        color.insert(a[v]);

                }
            }
        }
    }
    // while(pq.size()){
    //     // queue<int> q1;
    //     {
    //         int u = pq.top();
    //         // q.pop();
    //         pq.pop();
    //         // if(vis[u]) continue;
    //         // q1.push(u);

    //         // vis[a[u]] = true;
    //         // cerr << u << '\n';
    //         // vis[u] = true;
    //         ans.push_back(u);
    //         for(auto v : g[u]){
    //             if(v == 5){
    //                 cerr << cnt[a[5]] << '\n';
    //             }
    //             ru[v]--;
    //             if(a[v] == a[u]){
    //                 if(ru[v] == 0)
    //                     pq.push(v);
    //             }else{
    //                 cnt[a[v]]--;
    //                 if(ru[v] == 0)
    //                     g1[a[v]].push_back(v);
    //                 if(cnt[a[v]] == 0){
    //                     for(auto x : g1[a[v]])
    //                         pq.push(x);
    //                 }
    //             }
    //         }
    //     }
    //     // while(!q1.empty()){
    //         // auto u = q1.front();
    //         // cerr << u << '\n';
    //     //     q1.pop();
    //     //     vis[u] = true;
    //     //     ans.push_back(u);
    //     //     for(auto v : g[u]){
    //     //         ru[v]--;
    //     //         if(a[v] == a[u]){
    //     //             if(ru[v] == 0)
    //     //                 q1.push(v);
    //     //         }else{
    //     //             cnt[a[v]]--;
    //     //             if(ru[v] == 0)
    //     //                 g1[a[v]].push_back(v);
    //     //             if(cnt[a[v]] == 0){
    //     //                 for(auto x : g1[a[v]])
    //     //                     q.push(x);
    //     //             }
    //     //         }
    //     //     }
    //     // }
    // }
    if(ans.size() != n){
        cout << "-1\n";
        return;
    }
    for(auto x : ans)
        cout << x << ' ';
    cout << '\n';
}
int main()
{
    // freopen("1.in", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int T;
    cin >> T;
    while(T--)
        solve();
    return 0;
}

summary

这场我们写出来的题感觉难度还是比较低的,还有点题能补的,但最近没空,以后看到再来吧。