重庆市第十三届程序设计大赛

problem

F、H

L

每次维护栈顶的n个元素,因为不会pop到后面的元素

C

稍微有点意思的一个构造,有很多不同的通过方案。感觉纯纯奇思妙想题。赛时队友秒了。
赛后因为不会妙妙构造,写了很暴力的构式实现(\(O(nlogn)\))草过去了

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
// #define int long long
const int N = 2e5 + 7, mod = 1e9 + 7;
int read() {
    int res = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9') {
        if (c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 + c - '0';
        c = getchar();
    }
    return res * f;
}
int add(int a, int b) {
    return (a + b) % mod ;
}
int mul(int a, int b) {
    return 1ll * a * b % mod;
}
int sub(int a, int b) {
    return (a+mod-b)%mod;
}
int qpow(int x, int y) {
    int res = 1;
    while(y) {
        if (y & 1) res = mul(res, x);
        x = mul(x, x);
        y >>= 1;
    }
    return res;
}
int vis[1015][1015];
void solve() {
    int n;
    cin >> n;
    int nw = 1;
    int num = 0;
    for (int i = 1; i <= n; i++) {
        vis[i][0] = 1;
        vis[i][i] = 1;
    }
    set<int>q;
    for (int i = 1; i <= n; i++) q.insert(i);
    for (int i = 1; i <= n; i++) {
        nw = *q.begin();
        for (int j = 1; j <= n; j++) {
            if (num == n) {
                cout << n << ' ';
                continue;
            }
            cout << nw << ' ';
            if (j == n) break;
            int b, lst = nw;
            b = vis[nw][0];
            while(b <= n && vis[nw][b]) b++, vis[nw][0]++;
            if(!q.empty() && b > n){
                q.erase(nw);
                num++;
                b = *q.begin();
            }
            if (b > n) continue;
            nw = b;
            vis[lst][b] = 1;
            vis[b][lst] = 1;
        }
        cout << endl;
    }

    for (int i = 0; i <= n; i++) for (int j = 0; j <= n; j++) vis[i][j] = 0;
}
signed main(){
    int t = 1;
    cin >> t;
    while(t--){
        solve();
    }
}

B

赛时队友贪心草过去了但是严禁证明是网络流的最大流最小割。
只要求最小割就可以了。
实现上是map离散化+差分(为什么用map离散化是个谜)

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
// #define int long long
const int N = 8e5 + 10, mod = 1e9 + 7;
int read() {
    int res = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9') {
        if (c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 + c - '0';
        c = getchar();
    }
    return res * f;
}
int add(int a, int b) {
    return (a + b) % mod ;
}
int mul(int a, int b) {
    return 1ll * a * b % mod;
}
int sub(int a, int b) {
    return (a+mod-b)%mod;
}
int qpow(int x, int y) {
    int res = 1;
    while(y) {
        if (y & 1) res = mul(res, x);
        x = mul(x, x);
        y >>= 1;
    }
    return res;
}
struct Node {
    int l, r, c;
}a[N];
LL b[N];
bool cmp(const Node &x, const Node &y) {
    return x.l < y.l;
}
void solve() {
    int n, m;
    cin >> n >> m;
    LL ans = 0x3f3f3f3f3f3f3f, sum = 0;
    map<int, int>mp;
    for (int i = 1; i <=m; i++) {
        cin >> a[i].l >> a[i].r >> a[i].c;
        mp[a[i].l] = a[i].l;
        mp[a[i].r] = a[i].r;
    }
    int tot = 0, mx = 0, mn = 0;
    for (auto &i : mp) {
        if (i.first == 1) mn = 1;
        tot++;
        i.second = tot;
        if (i.first == n) mx = tot;
        // tot++;
    }
    sort(a + 1, a + m + 1, cmp);
    for (int i = 1; i <= m; i++) {
        a[i].l = mp[a[i].l];
        a[i].r = mp[a[i].r];
        b[a[i].l] += a[i].c;
        b[a[i].r] -= a[i].c;
    }
    for (int i = 1; i <= mx - 1; i++) {
        sum += b[i];
        ans = min(sum, ans);
        b[i] = 0;
    }
    for (int i = mx; i <= tot; i++) b[i] = 0;
    if (mx && mn) cout << ans << endl;
    else cout << 0 << endl;
}
signed main(){
    int t = 1;
    cin >> t;
    while(t--){
        solve();
    }
}

J

白色的点会构成一个连通块(在树中间)
所以就统计至少中间要有多少白点,这个不好统计所以去统计不需要涂的点

D

以下待补

E

I

posted @ 2025-05-29 22:01  lyrrr  阅读(23)  评论(0)    收藏  举报