T624534 前置条件

  1. 问题分析

    • 题目要求判断字符串S中所有不在开头位置的大写字母,其前一个字符是否都出现在字符串T中

    • 第一个字符如果是大写字母不需要检查前驱字符

  2. 关键步骤

    • 预处理阶段:使用标记数组vis记录T中所有出现的字符

    • 检查阶段

      • 遍历S字符串,从第二个字符开始检查

      • 遇到大写字母时,检查其前一个字符是否在T中

      • 如果发现不符合条件的字符,立即标记并终止检查

  3. 优化点

    • 使用标记数组vis实现O(1)时间的字符存在性检查

    • 遇到第一个不符合条件的情况立即终止,提高效率

    • 使用cnt变量记录已发现的大写字母数量,优化判断逻辑

  4. 复杂度分析

    • 时间复杂度:O(n+m),其中n是S的长度,m是T的长度

    • 空间复杂度:O(1),仅使用固定大小的标记数组

  5. 注意事项

    • 题目明确说明只检查非开头位置的大写字母

    • T中的字符包括大小写字母,需要全部考虑

    • 使用ASCII码值作为数组索引,确保所有字符都能被正确表示

  6. 参考程序
#include<bits/stdc++.h>
using namespace std;

string S, T;       // 定义字符串S和T
bool vis[200];      // 标记数组,用于记录T中的字符

int main() {
    // 输入两个字符串S和T
    cin >> S >> T;
    
    // 预处理:标记T中出现的所有字符
    for (int i = 0; i < T.size(); i++) {
        vis[T[i]] = 1;  // 将T中的字符对应的ASCII码位置标记为1
    }

    bool f = 1;         // 标记是否满足条件,初始为满足
    int cnt = 0;        // 统计S中大写字母的数量
    
    // 检查第一个字符是否为大写
    cnt += (S[0] >= 'A' && S[0] <= 'Z'); 
    
    // 从第二个字符开始检查
    for (int i = 1; i < S.size(); i++) {
        // 如果当前字符是大写字母
        if(S[i] >= 'A' && S[i] <= 'Z') {
            cnt++;  // 大写字母计数增加
            
            // 检查前一个字符是否在T中,且不是第一个大写字母
            if(vis[S[i-1]] == 0 && cnt >= 1) {
                f = 0;  // 不满足条件
                break;  // 提前退出循环
            }
        }
    }
    
    // 输出结果
    if(f) cout << "Yes";
    else cout << "No";

    return 0;
}

 

posted @ 2025-06-29 11:55  行胜于言Ibl  阅读(13)  评论(0)    收藏  举报