window.cnblogsConfig = {//可以放多张照片,应该是在每一个博文上面的图片,如果是多张的话,那么就随机换的。 homeTopImg: [ "https://cdn.luogu.com.cn/upload/image_hosting/xkzro04i.png" ], }

2023.11.10 测试复盘

$2023.11.10$ 测试复盘

总分:$100+50+70=220$

一道水题。直接模拟即可。时间复杂度:$O(Tn)$

${\color{#52C41A} \texttt{AC}}$ Code:

#include <cstdio>
#include <cstring>
using namespace std;

char s[103];

int main() {
    int _;
    scanf("%d", &_);
    while(_--) {
        scanf("%s", s + 1);
        int cntu = 0, cntl = 0, n = strlen(s + 1);
        for(int i = 1; i <= n; ++i)
            if('A' <= s[i] && s[i] <= 'Z')
                ++cntu;
            else if('a' <= s[i] && s[i] <= 'z')
                ++cntl;
        if(cntu > cntl)
            for(int i = 1; i <= n; ++i)
                if('a' <= s[i] && s[i] <= 'z')
                    putchar(s[i] - 32);
                else
                    putchar(s[i]);
        else
            for(int i = 1; i <= n; ++i)
                if('A' <= s[i] && s[i] <= 'Z')
                    putchar(s[i] + 32);
                else
                    putchar(s[i]);
        putchar('\n');
    }
    return 0;
}

这道题是三道题中最难的一道(反正老师和大部分同学这么认为)。我用枚举+前缀和优化拿到 $50 \text{pts}$,时间复杂度 $O(n^2)$。正解是枚举第二条分界线,然后判断是否存在合理的第一条分界线,最后根据乘法原理可得答案。

${\color{#52C41A} \texttt{AC}}$ Code:

#include <cstdio>
#include <map>
using namespace std;
using LL = long long;

const int N = 100003;
map<int, int> mp;
LL a[N], qzh[N], hzh[N];

int main() {
    int n;
    LL tot = 0, ans = 0;
    scanf("%d", &n);
    if(n < 3)
    {
        putchar('0');
        return 0;
    }
    for(int i = 1; i <= n; ++i)
    {
        scanf("%lld", &a[i]);
        tot += a[i];
        qzh[i] = qzh[i - 1] + a[i];
    }
    for(int i = n; i >= 1; --i)
    {
        hzh[i] = hzh[i + 1] + a[i];
        ++mp[hzh[i]];
    }
    --mp[hzh[1]];
    for(int i = 1; i < n - 1; ++i)
    {
        --mp[hzh[i + 1]];
        if(qzh[i] * 3 == tot)
            ans += mp[qzh[i]];
    }
    printf("%lld", ans);
    return 0;
}

这道题难度中等,主要考验思维,代码实现比较简单。思路是:

  1. 分析可知,第一个数要么是 $0$ 要么是 $3$。如果 $n < 3$,则直接输出 $0$。

  2. 然后可知,对于第 $i$ 个数,我们要找 $a_j$ 和 $a_k$ 满足 $a_j < a_i < a_k (1 \le j < i < k \le n)$。而这个可以通过打表预处理得到。

时间复杂度:$O(n)$

${\color{#52C41A} \texttt{AC}}$ Code:

#include <cstdio>
using namespace std;

const int N = 100003;
int min1[N]{0, 1}, min2[N], max1[N]{0, 1}, max2[N], num[N];

int main() {
    int n;
    scanf("%d", &n);
    if(n < 3)
    {
        printf("0");
        return 0;
    }
    for(int i = 1; i <= n; ++i)
        scanf("%d", &num[i]);
    for(int i = 2; i < n; ++i)
    {
        if(num[max1[i - 1]] > num[i])
            max1[i] = max1[i - 1];
        else
            max1[i] = i;
        if(num[min1[i - 1]] < num[i])
            min1[i] = min1[i - 1];
        else
            min1[i] = i;
    }
    min2[n] = max2[n] = n;
    for(int i = n - 1; i > 0; --i)
    {
        if(num[max2[i + 1]] > num[i])
            max2[i] = max2[i + 1];
        else
            max2[i] = i;
        if(num[min2[i + 1]] < num[i])
            min2[i] = min2[i + 1];
        else
            min2[i] = i;
    }
    int i;
    for(i = 2; i < n; ++i)
    {
        if(num[max1[i - 1]] > num[i] && num[max2[i + 1]] > num[i])
        {
            printf("3\n%d %d %d", max1[i - 1], i, max2[i + 1]);
            break;
        }
        if(num[min1[i - 1]] < num[i] && num[min2[i + 1]] < num[i])
        {
            printf("3\n%d %d %d", min1[i - 1], i, min2[i + 1]);
            break;
        }
    }
    if(i == n)
        printf("0");
    return 0;
}
posted @ 2023-11-10 22:24  TigerTanWQY  阅读(17)  评论(0)    收藏  举报  来源