1 条题解

  • 0
    @ 2025-5-19 13:23:51

    题意分析

    题目要求检测电子邮件内容是否违反四项特定的礼仪规则,具体规则如下:

    1. 连续两个大写字母

      • 例如DONTDON'T中的DODONTNT(忽略标点)。
      • 可能暗示用户在大声喊叫。
    2. 数字与字母直接相邻

      • 例如bb l8l8中的l8l8
      • 常见于网络俚语(如l33tl33td00dd00d)。
    3. 孤立的非aa/AA/II单字符

      • 孤立字符定义为前后均为空格或字符串边界的单字符。
      • 例如uu rr中的uurr(非aaAAII)。
    4. 相邻的两个标点符号(双引号"除外)

      • 例如:):-)中的::-
      • 可能包含表情符号。

    解题思路

    关键点分析

    1. 规则实现

      • 连续大写字母:遍历字符串,检查是否存在连续两个字母均为大写。
      • 数字与字母相邻:检查数字和字母的直接相邻情况(包括数字后字母和字母后数字)。
      • 孤立非aa/AA/II单字符
        • 孤立字符的条件:前后为空格或边界。
        • 排除aaAAII
      • 相邻标点符号
        • 标点符号定义为非字母、数字、空格的字符。
        • 排除双引号"
    2. 字符分类

      • 使用ASCII值判断字符类型(字母、数字、空格、标点)。
    3. 边界处理

      • 字符串首尾的特殊情况(孤立字符)。
      • 标点符号的排除规则(双引号)。

    解决步骤

    1. 输入处理

      • 逐行读取邮件内容,直到遇到#
    2. 规则检查

      • 对每条邮件,依次检查四项规则:
        1. 连续大写字母。
        2. 数字与字母相邻。
        3. 孤立非aa/AA/II单字符。
        4. 相邻标点符号(非")。
    3. 结果输出

      • 若触发任意规则,输出suspicioussuspicious
      • 否则输出OKOK

    算法复杂度

    • 时间复杂度:O(n)O(n),其中nn为邮件长度(最多8080字符)。
    • 空间复杂度:O(1)O(1),仅需常数空间存储中间状态。

    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    
    int is_punctuation(char c) {
        return !isalnum(c) && c != ' ' && c != '"';
    }
    
    int is_suspicious(const char *line) {
        int len = strlen(line);
        
        // 规则1:连续两个大写字母
        for (int i = 0; i < len - 1; i++) {
            if (isupper(line[i]) && isupper(line[i+1])) {
                return 1;
            }
        }
        
        // 规则2:数字与字母相邻
        for (int i = 0; i < len - 1; i++) {
            if ((isdigit(line[i]) && isalpha(line[i+1])) ||
                (isalpha(line[i]) && isdigit(line[i+1]))) {
                return 1;
            }
        }
        
        // 规则3:孤立的非a/A/I单字符
        for (int i = 0; i < len; i++) {
            if (line[i] != ' ' && (i == 0 || line[i-1] == ' ') && 
                (i == len - 1 || line[i+1] == ' ')) {
                if (line[i] != 'a' && line[i] != 'A' && line[i] != 'I') {
                    return 1;
                }
            }
        }
        
        // 规则4:相邻的两个标点符号(双引号除外)
        for (int i = 0; i < len - 1; i++) {
            if (is_punctuation(line[i]) && is_punctuation(line[i+1]) &&
                line[i] != '"' && line[i+1] != '"') {
                return 1;
            }
        }
        
        return 0;
    }
    
    int main() {
        char line[82];
        
        while (1) {
            fgets(line, sizeof(line), stdin);
            line[strcspn(line, "\n")] = '\0'; // 移除换行符
            
            if (strcmp(line, "#") == 0) {
                break;
            }
            
            if (is_suspicious(line)) {
                printf("suspicious\n");
            } else {
                printf("OK\n");
            }
        }
        
        return 0;
    }
    
    • 1

    信息

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