2023 年 3 月青少年软编等考 C 语言四级真题解析

T1. 最佳路径

题目链接:SOJ D1079

此题为 2021 年 6 月四级第一题原题,见 2021 年 6 月青少年软编等考 C 语言四级真题解析中的 T1。

T2. 邮票收集

题目链接:SOJ D1031

此题为 2020 年 12 月四级第二题原题,见 2020 年 12 月青少年软编等考 C 语言四级真题解析中的 T2。

T3. 切割回文

题目链接:SOJ D1244

阿福最近对回文串产生了非常浓厚的兴趣。

如果一个字符串从左往右看和从右往左看完全相同的话,那么就认为这个串是一个回文串。例如, a b c a a c b a \tt abcaacba abcaacba 是一个回文串, a b c a a b a \tt abcaaba abcaaba 则不是一个回文串。

阿福现在强迫症发作,看到什么字符串都想要把它变成回文的。阿福可以通过切割字符串,使得切割完之后得到的子串都是回文的。

现在阿福想知道他最少切割多少次就可以达到目的。例如,对于字符串 a b a a c c a \tt abaacca abaacca,最少切割一次,就可以得到 a b a \tt aba aba a c c a \tt acca acca 这两个回文子串。

时间限制:1 s
内存限制:64 MB

  • 输入
    输入的第一行是一个整数 T   ( T ≤ 20 ) T\ (T \le 20) T (T20),表示一共有 T T T 组数据。
    接下来的 T T T 行,每一行都包含了一个长度不超过的 1000 1000 1000 的字符串,且字符串只包含了小写字母。
  • 输出
    对于每组数据,输出一行。该行包含一个整数,表示阿福最少切割的次数,使得切割完得到的子串都是回文的。
  • 样例输入
    3
    abaacca
    abcd
    abcba
    
  • 样例输出
    1
    3
    0
    
  • 提示
    对于第一组样例,阿福最少切割 1 1 1 次,将原串切割为 a b a \tt aba aba a c c a \tt acca acca 两个回文子串。
    对于第二组样例,阿福最少切割 3 3 3 次,将原串切割为 a \tt a a b \tt b b c \tt c c d \tt d d 这四个回文子串。
    对于第三组样例,阿福不需要切割,原串本身就是一个回文串。

思路分析

此题考查动态规划,属于基础题。

显然这里应该以序列长度为阶段,定义 f i f_i fi 表示前 i i i 个字符切割成回文串所需要的最少切割次数,于是我们可以枚举断点 k k k,当检测到 s [ k . . i ] s[k.. i] s[k..i] 为回文串时, f i = min ⁡ { f k − 1 + 1 } f_i = \min\{f_{k-1}+1\} fi=min{fk1+1}。初始状态为 f 1 = 0 f_1 = 0 f1=0,如果 s [ 1.. i ] s[1..i] s[1..i] 是回文串,则 f i = 0 f_i = 0 fi=0,其余均为 i n f inf inf,最终 f n f_n fn 即为答案。

/*
 * Name: T3.cpp
 * Problem: 切割回文
 * Author: Teacher Gao.
 * Date&Time: 2024/12/19 18:50
 */

#include <iostream>
#include <cstring>

using namespace std;

char s[1005] = " ";
bool check(int x, int y)
{
    for (int i = x, j = y; i < j; i++, j--)
        if (s[i] != s[j])
            return false;
    
    return true;
}

int main()
{
    int t, f[1005];
    
    scanf("%d", &t);
    while (t--) {
        scanf(" %s", s + 1);
        int len = strlen(s) - 1;

        memset(f, 0x3f, sizeof(f));
        f[1] = 0;
        for (int j = 1; j <= len; j++) {
            if (check(1, j)) f[j] = 0;
            for (int k = 2; k <= j; k++)
                if (check(k, j))
                    f[j] = min(f[j], f[k-1] + 1);
        }

        printf("%d\n", f[len]);
    }

    return 0;
}

T4. 小球放盒子

题目链接:SOJ D1082

此题为 2021 年 6 月四级第四 题原题,见 2021 年 6 月青少年软编等考 C 语言四级真题解析中的 T4。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南朔 Clancy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值