比赛总结:CF2059 R1002 D2

赛时得分:\(1/6\)

rank:\(10939\)

题目链接:CF2059

PS:赛时被 B 卡了一整场,赛后把 CD 秒了,瞬间红温。反思一下自己为什么会被卡,遇到 Ad-hoc 题就做得慢。

A

\(a\) 中不同数的个数为 \(x\)\(b\) 中不同数的个数为 \(y\),无合法方案当且仅当 \(x+y\le 3\),其他情况一定能构造出合法方案。

B

\(n=k\),则答案固定。

\(n\neq k\)

  • 若要使答案是 \(1\),可以在 \(2\le i\le n-(k-2)\) 中找到一个不是 \(1\) 的数,使得它为第二个子数组的第一位,即可。

  • \(2\le i\le n-(k-2)\) 都是 \(1\),因为 \(k<n\),所以 \(n-(k-2)\ge 3\),所以中间一定存在 \(\ge 2\)\(1\),直接把 \([1, 1]\) 分配到第二个子数组的前两位,即可使答案为 \(2\)

因此 \(n\neq k\) 的情况答案 \(\in \{1, 2\}\)

C

每个队列最多只会操作一次。

那么等价于对每个队列,留下一段后缀和作为它的最终人数。

又因为每一时刻只能操作一次,那么每一列(假设是第 \(j\) 列)最多只能留下一个以 \(a_{i,j}\) 为开头的后缀。

如果我们对 \(a\) 的每一行做后缀和(\(a_{i,n+1}\) 位置的后缀和为 \(0\)),将后缀和数组记为 \(s\),那么原问题等价于从 \(s\) 中选择一些数,使得它们在不同行不同列,要求选出来的数的 \(\operatorname{mex}\) 最大。

重要条件:每个元素都是正整数。

根据这个条件,首先 \(s_{i,n+1}\)\(0\) 一定要选,因为其他地方不会出现 \(0\)。然后 \(s_{i,n}\)\(1\) 一定要选,因为其他地方不会出现 \(1\),······

于是我们发现,只有 \(s_{i,j}=n-j+1\) 的位置是有用的,对应到 \(a\) 就是只有每一行的后缀 \(1\) 是有用的。

那么我们把 \(s\) 的这些位置排个序,贪心的选就好了。

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

const int N = 3e2 + 5, INF = 2e9;

int n;
ll a[N][N];

void Solve() {
    cin >> n;
    vector<int> rec;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> a[i][j];
        }
        a[i][n + 1] = 0;
        for (int j = n; j >= 1; j--) {
            a[i][j] += a[i][j + 1];
        }
        for (int j = 1; j <= n + 1; j++) {
            if (a[i][j] == n - j + 1) {
                rec.push_back(a[i][j]);
                break;
            }
        }
    }
    sort(rec.begin(), rec.end());
    int cur = 0;
    for (int i : rec) {
        if (i >= cur) cur++;
    }
    cout << cur << '\n';
}

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

D

存在有限答案,当且仅当 \(s_1\) 可以走到一条边 \((u_1,v_1)\)\(s_2\) 同时可以走到一条边 \((u_2, v_2)\),使得 \(u_1=u_2\)\(v_1=v_2\)

\(dis_{u,v}\) 表示 \(s_1\) 走到 \(u\)\(s_2\) 同时走到 \(v\) 的最小代价,然后 dijkstra 计算最短路即可。

统计答案的时候就 \(O(n^2)\) 枚举一下 \((u,v)\) 即可。

Code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using Pii = pair<int, int>;

const int N = 1e3 + 5, INF = 2e9;

int n, m1, m2, s1, s2;
vector<int> G1[N], G2[N];
int dis[N][N];
bool vis[N][N], E1[N][N], E2[N][N];

struct CMP {
    bool operator() (const Pii& a, const Pii& b) const {
        return dis[a.first][a.second] > dis[b.first][b.second];
    }
};

void dijkstra() {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            dis[i][j] = INF;
        }
    }
    priority_queue<Pii, vector<Pii>, CMP> pq;
    dis[s1][s2] = 0;
    pq.emplace(s1, s2);
    while (!pq.empty()) {
        int u1 = pq.top().first, u2 = pq.top().second;
        pq.pop();
        if (vis[u1][u2]) continue;
        vis[u1][u2] = true;
        for (int v1 : G1[u1]) {
            for (int v2 : G2[u2]) {
                if (dis[v1][v2] > dis[u1][u2] + abs(v1 - v2)) {
                    dis[v1][v2] = dis[u1][u2] + abs(v1 - v2);
                    pq.emplace(v1, v2);
                }
            }
        }
    }
}

void Solve() {
    cin >> n >> s1 >> s2;
    cin >> m1;
    int u, v;
    for (int i = 1; i <= m1; i++) {
        cin >> u >> v;
        G1[u].push_back(v);
        G1[v].push_back(u);
        E1[u][v] = E1[v][u] = true;
    }
    cin >> m2;
    for (int i = 1; i <= m2; i++) {
        cin >> u >> v;
        G2[u].push_back(v);
        G2[v].push_back(u);
        E2[u][v] = E2[v][u] = true;
    }
    dijkstra();
    int ans = INF;
    // cout << "dis:\n";
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            // cout << dis[i][j] << ' ';
            if (j != i && E1[i][j] && E2[i][j]) {
                ans = min(ans, dis[i][i]);
            }
        }
        // cout << '\n';
    }
    cout << (ans == INF ? -1 : ans) << '\n';
    for (int i = 1; i <= n; i++) {
        G1[i].clear();
        G2[i].clear();
        for (int j = 1; j <= n; j++) {
            vis[i][j] = E1[i][j] = E2[i][j] = false;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while (T--) Solve();
    return 0;
}
posted @ 2025-02-03 17:50  chenwenmo  阅读(20)  评论(0)    收藏  举报