Atcoder Beginner Contest 395

比赛链接:Atcoder Beginner Contest 395
Github 链接:ABC395

A - Strictly Increasing?

按照题意模拟。

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

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    bool flag = true;
    for (int i = 1; i < n; i++)
        if (a[i] <= a[i - 1]) {
            flag = false;
            break;
        }
    if (flag) cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}

B - Make Target

按照题意模拟。

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

char s[55][55];

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int j = n - i + 1;
        if (i <= j) {
            char c;
            if (i & 1) c = '#';
            else c = '.';
            for (int x = i; x <= j; x++)
                for (int y = i; y <= j; y++) s[x][y] = c;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cout << s[i][j];
        }
        cout << endl;
    }
    return 0;
}

C - Shortest Duplicate Subarray

对于每一个相同的 \(a\) 的值,记录他们的下标,答案是相距最近的两个相同的 \(a\) 值的距离

时间复杂度:\(O(N + A)\)\(A\) 代表 \(A_i\) 的最大值)。

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

const int N = 2e5 + 10;
int n, a[N], maxm = 0;

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        maxm = max(a[i], maxm);
    }
    vector<vector<int>> vis(maxm + 1);
    for (int i = 1; i <= n; i++) vis[a[i]].push_back(i);
    int ans = INT_MAX;
    for (int i = 1; i <= maxm; i++) {
        if (vis[i].size() >= 2) {
            for (int j = 1; j < vis[i].size(); j++)
                ans = min(ans, vis[i][j] - vis[i][j - 1] + 1);
        }
    }
    if (ans != INT_MAX) cout << ans << endl;
    else cout << -1 << endl;
    return 0;
}

D - Pigeon Swap

  • 对于第一种操作,只需要对每一个鸽子记录一个 \(f_i\),表示第 \(i\) 只鸽子所在的鸟巢编号。
  • 对于第二种操作,
    • 要将所有 \(f_i = a\) 的位置,变成 \(f_i = b\)
    • 同时将所有 \(f_i = b\) 的位置,变成 \(f_i = a\)
      如果暴力的做,那么时间复杂度是 \(O(n)\),无法满足题目限制。
  • 可以发现 \(f_i\) 的值跟最终的鸟巢编号存在一个映射的关系,所以记录一个 \(pos_i\) 来表示这个映射关系。初始化 \(pos_i = i\),表示最开始每一个 \(f_i\) 的值都表示对应的鸟巢。对于第二种操作,只需要更改对应的映射关系即可,即交换 \(pos_a\)\(pos_b\) 的值。
  • 但此事第一个操作就不能直接赋值 \(f_i = b\) 了,而是要让 \(f_i = j\)\(pos_j = b\)),所以要另外再记一个 \(idx_i\) 作为跟 \(pos_i\) 刚好相反的一个映射,方便进行操作一。

在这样的情况下,

  • 操作一实际上就是让 \(f_a = idx_b\)
  • 操作二实际上是要分别交换 (\(pos_{idx_a}\), \(pos_{idx_b}\)),跟(\(pos_a\), \(pos_b\))。
  • 操作三实际上是要输出 \(pos_{f_a}\)

时间复杂度:\(O(N + Q)\)

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

const int N = 1e6 + 10;
int n, q, f[N], pos[N], idx[N];

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    cin >> n >> q;
    for (int i = 1; i <= n; i++) f[i] = pos[i] = idx[i] = i;
    while (q--) {
        int op, a, b;
        cin >> op;
        if (op == 1) {
            cin >> a >> b;
            f[a] = idx[b];
        }
        if (op == 2) {
            cin >> a >> b;
            swap(pos[idx[a]], pos[idx[b]]);
            swap(idx[a], idx[b]);
        }
        if (op == 3) {
            cin >> a;
            cout << pos[f[a]] << '\n';
        }
    }
    return 0;
}

E - Flip Edge

对于每一对给出的 \((u, v)\),直接连一条有向边,权值为 \(1\)

为了表示翻转操作,可以给 \((v + n, u + n)\) 连一条边,权值为 \(1\),并且对于 \(1 \le i \le n\),连 \((i, i + n)\)\((i + n, i)\) 两条边,权值都设为 \(x\)

接着,直接从 \(1\) 号节点开始跑 \(dijsktra\),最后的答案为 \(\min(dis_n, dis_{2n})\)

时间复杂度:\(O(n\log n)\)

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

#define int long long

const int N = 2e5 + 10, M = N << 3;
int n, m, x, head[N << 1], num = 0, dis[N << 1], vis[N << 1] = { 0 };
struct edge { int to, nxt, w; } e[M];
struct node {
    int u, d;
    bool operator< (const node &curNode) const {
        return curNode.d < d;
    }
};

void addEdge(int u, int v, int w) { e[++num] = (edge){ v, head[u], w}, head[u] = num; }

void dijsktra(int s) {
    for (int i = 1; i <= 2 * n; i++) dis[i] = LLONG_MAX;
    dis[s] = 0;
    priority_queue<node> q;
    q.push({s, 0});
    while (!q.empty()) {
        int u = q.top().u; q.pop();
        if (vis[u]) continue;
        vis[u] = 1;
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to, w = e[i].w;
            if (dis[v] > dis[u] + w) {
                dis[v] = dis[u] + w;
                q.push({v, dis[v]});
            }
        }
    }
}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    cin >> n >> m >> x;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        addEdge(u, v, 1), addEdge(v + n, u + n, 1);
    }
    for (int i = 1; i <= n; i++) addEdge(i, i + n, x), addEdge(i + n, i, x);
    dijsktra(1);
    cout << min(dis[n], dis[2 * n]) << endl;
    return 0;
}

F - Smooth Occlusion

可以发现 \(H\) 满足单调性(\(H\) 越大花费越少),我们可以二分 \(H\),然后 \(O(n)\) 检查是不是符合条件。

检查实现:

  • 对于每一个位置 \(i\),需要进行的消除次数是 \(U_i + D_i - H\)
  • 为了满足 \(|U_i - U_{i + 1}| \le X\) 的条件,\(U_{i + 1}\) 可行的范围是 \([\min U_i - X, \max U_i + X]\)
  • \(\min U_i = \max(0, U_i - (U_i + D_i - H)) = \max (0, H - D_i)\)\(\max U_i = U_i\)

时间复杂度:\(O(N \log(U_i + D_i))\)

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

#define int long long

const int N = 2e5 + 10;
int n, x, u[N], d[N];

bool check(int mid) {
    int l = LLONG_MIN, r = LLONG_MAX;
    for (int i = 1; i <= n; i++) {
        l = max(l, max(0LL, mid - d[i])), r = min(r, u[i]);
        if (l > r) return false;
        l -= x, r += x;
    }
    return true;
}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    cin >> n >> x;
    int l = 0LL, r = LLONG_MAX, tar = 0LL;
    for (int i = 1; i <= n; i++) cin >> u[i] >> d[i], r = min(r, u[i] + d[i]);
    while (l <= r) {
        int mid = l + r >> 1;
        if (check(mid)) l = mid + 1, tar = mid;
        else r = mid - 1;
    }
    int ans = 0LL;
    for (int i = 1; i <= n; i++) ans += u[i] + d[i] - tar;
    cout << ans << endl;
    return 0;
}
posted @ 2025-06-25 10:40  nuo534202  阅读(0)  评论(0)    收藏  举报