1 条题解
-
0
题意分析
题目要求检测电子邮件内容是否违反四项特定的礼仪规则,具体规则如下:
-
连续两个大写字母:
- 例如中的和(忽略标点)。
- 可能暗示用户在大声喊叫。
-
数字与字母直接相邻:
- 例如 中的。
- 常见于网络俚语(如、)。
-
孤立的非//单字符:
- 孤立字符定义为前后均为空格或字符串边界的单字符。
- 例如 中的和(非、或)。
-
相邻的两个标点符号(双引号
"
除外):- 例如中的和。
- 可能包含表情符号。
解题思路
关键点分析
-
规则实现:
- 连续大写字母:遍历字符串,检查是否存在连续两个字母均为大写。
- 数字与字母相邻:检查数字和字母的直接相邻情况(包括数字后字母和字母后数字)。
- 孤立非//单字符:
- 孤立字符的条件:前后为空格或边界。
- 排除、、。
- 相邻标点符号:
- 标点符号定义为非字母、数字、空格的字符。
- 排除双引号
"
。
-
字符分类:
- 使用ASCII值判断字符类型(字母、数字、空格、标点)。
-
边界处理:
- 字符串首尾的特殊情况(孤立字符)。
- 标点符号的排除规则(双引号)。
解决步骤
-
输入处理:
- 逐行读取邮件内容,直到遇到
#
。
- 逐行读取邮件内容,直到遇到
-
规则检查:
- 对每条邮件,依次检查四项规则:
- 连续大写字母。
- 数字与字母相邻。
- 孤立非//单字符。
- 相邻标点符号(非
"
)。
- 对每条邮件,依次检查四项规则:
-
结果输出:
- 若触发任意规则,输出。
- 否则输出。
算法复杂度
- 时间复杂度:,其中为邮件长度(最多字符)。
- 空间复杂度:,仅需常数空间存储中间状态。
#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
- 上传者