AcWing第3场周赛题解

A. AcWing 3660. 最短时间

题目链接:https://www.acwing.com/problem/content/3663/

题目大意:求 \(n \times m\) 的矩阵中所有各自到 \((r,c)\) 的最短距离。

解题思路:四角的各自的距离的最大值。

示例程序:

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

int T, n, m, r, c;

int main() {
    cin >> T;
    while (T--) {
        cin >> n >> m >> r >> c;
        cout << max(r-1, n-r) + max(c-1, m-c) << endl;
    }
    return 0;
}

B. AcWing 3661. 重置数列

题目链接:https://www.acwing.com/problem/content/3664/

题目大意:按照题目要求进行操作,求最少次数。

解题思路:由于 \(1 \le a_i \le 100\),所有可以先 枚举答案,再 贪心 处理。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int T, n, k, a[maxn], ans;

int solve(int x) {
    int p = 0, cnt = 0;
    while (p < n) {
        if (a[p] == x) p++;
        else {
            p += k;
            cnt++;
        }
    }
    return cnt;
}

int main() {
    cin >> T;
    while (T--) {
        cin >> n >> k;
        for (int i = 0; i < n; i++) cin >> a[i];
        ans = (n - 1) / k + 1;
        for (int i = 1; i <= 100; i++)
            ans = min(ans, solve(i));
        cout << ans << endl;
    }
    return 0;
}

C. AcWing 3662. 最大上升子序列和

题目链接:https://www.acwing.com/problem/content/3665/

题目大意:求最大上升子序列和。

解题思路:

\(f_i\) 表示以 \(a_i\) 结尾(且包含 \(a_i\))的最大上升子序列和,则 \(f_i\) 应该是 \(a_i\) 及所有满足 \(j \lt i\)\(a_j \lt a_i\)\(f_j + a_i\) 的最大值。

但是直接求时间复杂度为 \(O(n^2)\) 会超时,但是可以对 \(a_i\) 做离散化然后用线段树维护这个东西。嗯就是这样。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, a[maxn], p[maxn];
long long tree[maxn<<2];
vector<int> vec;

void push_up(int rt) {
    tree[rt] = max(tree[rt<<1], tree[rt<<1|1]);
}

#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1

long long query(int L, int R, int l, int r, int rt) {
    if (L <= l && r <= R) return tree[rt];
    long long res = 0;
    int mid = (l + r) / 2;
    if (L <= mid) res = query(L, R, lson);
    if (R > mid) res = max(res, query(L, R, rson));
    return res;
}

void update(int p, long long v, int l, int r, int rt) {
    if (l == r) {
        tree[rt] = max(tree[rt], v);
        return;
    }
    int mid = (l + r) / 2;
    if (p <= mid) update(p, v, lson);
    else update(p, v, rson);
    push_up(rt);
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        vec.push_back(a[i]);
    }
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
    int m = vec.size();
    for (int i = 0; i < n; i++)
        p[i] = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin() + 1;
    for (int i = 0; i < n; i++) {
        int pp = p[i];
        if (pp == 1) update(pp, a[i], 1, m, 1);
        else {
            long long tmp = query(1, pp-1, 1, m, 1) + a[i];
            update(pp, tmp, 1, m, 1);
        }
    }
    cout << query(1, m, 1, m, 1) << endl;
    return 0;
}
posted @ 2022-04-07 14:04  quanjun  阅读(23)  评论(0编辑  收藏  举报