1 条题解

  • 0
    @ 2026-5-16 16:24:39

    B. pspspsps 题解

    题目回顾

    给定长度为 nn、仅含 p/s/. 的字符串 ss,判断是否存在一个 1n1 \sim n 的排列 pp,满足:

    1. si=ps_i=\texttt{p}:前缀 [p1,p2,,pi][p_1,p_2,\dots,p_i] 是长度为 ii 的排列;
    2. si=ss_i=\texttt{s}:后缀 [pi,pi+1,,pn][p_i,p_{i+1},\dots,p_n] 是长度为 ni+1n-i+1 的排列;
    3. si=.s_i=\texttt{.}:无任何限制。

    核心结论(解题关键)

    这道题的唯一矛盾点是约束冲突,我们只需要两步判断:

    1. 特殊位置无约束
      • 11 个位置的 s 无效(整个数组本身就是排列),直接视为 .
      • 最后 11 个位置的 p 无效(整个数组本身就是排列),直接视为 .
    2. 最终判定 处理后,若字符串中同时存在 ps → 输出 NO(约束冲突,无解); 否则 → 输出 YES(一定能构造出合法排列)。

    结论证明

    1. 仅含 p:构造排列 [1,2,3,,n][1,2,3,\dots,n],所有前缀天然满足排列要求;
    2. 仅含 s:构造排列 [n,n1,,1][n,n-1,\dots,1],所有后缀天然满足排列要求;
    3. 仅含 .:任意排列都合法;
    4. 同时含 ps:前缀约束和后缀约束无法同时满足,无解

    代码逐段解析

    主函数

    int main()
    {
        int t; cin >> t;
        for (int i = 0; i < t; i++) solve();
        return 0;
    }
    
    • 多组测试用例,循环调用求解函数,逻辑简洁。

    核心求解函数 solve()

    void solve()
    {
        int n; cin >> n;
        string s; cin >> s;
        
        // 步骤1:处理无意义的特殊字符
        if (s[0] == 's') s[0] = '.';   // 第一个位置的s无效
        if (s.back() == 'p') s.back() = '.'; // 最后一个位置的p无效
        
        // 步骤2:检查是否同时存在p和s
        bool found_p = false;
        bool found_s = false;
        for (const auto c : s)
        {
            if (c == 'p') found_p = true;
            if (c == 's') found_s = true;
        }
        
        // 步骤3:输出答案
        cout << (found_p && found_s ? "NO" : "YES") << '\n';
    }
    

    关键操作说明

    1. 无效字符处理
      • i=1i=1s 的约束是「整个数组是排列」,这是排列的定义,天然满足,因此直接改为 .
      • i=ni=np 的约束是「整个数组是排列」,同理天然满足,直接改为 .
    2. 冲突检测 遍历字符串,标记是否同时存在 ps,这是唯一的无解情况。

    复杂度分析

    • 时间复杂度O(n)O(\sum n) 每组测试用例仅遍历字符串一次,总长度不超过 50005000,完全满足 11 秒时间限制。
    • 空间复杂度O(n)O(n) 仅存储输入字符串,无额外空间开销。

    样例验证

    我们用题目样例验证代码逻辑:

    1. s.sp → 处理后 .sp → 含 ps?❌ → 输出 YES
    2. pss..s → 处理后含 ps → 输出 NO
    3. ppppp → 仅含 p → 输出 YES
    4. sp → 处理后 .p → 仅含 p → 输出 YES

    完全匹配题目样例输出!


    总结

    这道题是构造+贪心思维题,不需要复杂算法,核心是看透无效约束和冲突条件

    1. 忽略首尾无意义的 s/p
    2. 仅判断是否同时存在 ps
    3. 代码极简,效率拉满,完美通过所有测试用例。
    • 1

    信息

    ID
    7126
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者