AcWing第16场周赛题解

A. 3955. 统一大小写

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

题目大意:略。

解题思路:循环一轮记录大小写字母出现次数,然后相应地进行大小写转换。

示例程序:

#include <bits/stdc++.h>
using namespace std;
int T, c;
char s[1110];

int main() {
    cin >> T;
    while (T--) {
        cin >> s;
        c = 0;
        for (int i = 0; s[i]; i++)
            isupper(s[i]) ? c++ : c--;
        for (int i = 0; s[i]; i++)
            s[i] = (c > 0) ? toupper(s[i]) : tolower(s[i]);
        puts(s);
    }
    return 0;
}

B. 3956. 截断数组

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

题目大意:将数组从中间截断,得到三个非空子数组。要求,三个子数组内各元素之和都相等。

解题思路:前缀和 + dp。划分的第一个位置对应前缀和 \(\frac{1}{3}\),划分的第二个位置对应前缀和 \(\frac{2}{3}\)

示例程序:

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

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        a[i] += a[i-1];
    }
    if (a[n] % 3) {
        cout << 0 << endl;
        return 0;
    }
    for (int i = 1; i < n; i++) {
        if (a[i] * 3 == a[n] * 2) ans += c1;
        if (a[i] * 3 == a[n]) c1++;
    }
    cout << ans << endl;
    return 0;
}

C. 3957. 子序列

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

题目大意:在数列中找三个下标同时满足:

  1. \(i \lt j \lt k\)
  2. \(a_i \lt a_j \gt a_k\)\(a_i \gt a_j \lt a_k\)

解题思路:

最短的要么没有,要么长度为 \(3\)

开四个数组,对应前缀最大值、前缀最小值、后缀最大值、后缀最小值的下标。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, a[maxn], f1[maxn], f2[maxn], f3[maxn], f4[maxn];

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    f1[1] = f3[1] = 1;
    for (int i = 2; i <= n; i++) {
        int p = f1[i-1];
        if (a[i] < a[p]) f1[i] = i;
        else f1[i] = f1[i-1];
        p = f3[i-1];
        if (a[i] > a[p]) f3[i] = i;
        else f3[i] = f3[i-1];
    }
    f2[n] = f4[n] = n;
    for (int i = n-1; i >= 1; i--) {
        int p = f2[i+1];
        if (a[i] < a[p]) f2[i] = i;
        else f2[i] = f2[i+1];
        p = f4[i+1];
        if (a[i] > a[p]) f4[i] = i;
        else f4[i] = f4[i+1];
    }
    for (int i = 2; i < n; i++) {
        int x = f1[i-1], y = f2[i+1];
        if (a[x] < a[i] && a[i] > a[y]) {
            cout << 3 << endl;
            cout << x << " " << i << " " << y << endl;
            return 0;
        }
        x = f3[i-1], y = f4[i+1];
        if (a[x] > a[i] && a[i] < a[y]) {
            cout << 3 << endl;
            cout << x << " " << i << " " << y << endl;
            return 0;
        }
    }
    cout << 0 << endl;
    return 0;
}
posted @ 2022-04-11 16:19  quanjun  阅读(16)  评论(0编辑  收藏  举报