1 条题解

  • 0

    1. 问题本质理解

    我们需要统计在每次听到"BULLSHIT"之前,所有不重复的非"BULLSHIT"单词的平均数量。就像在课堂上记录老师说的不同术语,直到有人喊出游戏结束词。

    2. 关键步骤分解

    graph TD
        A[读取输入文本] --> B[分割单词]
        B --> C{是BULLSHIT?}
        C -->|是| D[结算当前游戏]
        C -->|否| E[记录单词]
        D --> F[计算平均值]
    

    3. 核心算法实现

    • 单词提取:用正则表达式 [a-zA-Z]+ 匹配纯字母单词
    • 大小写处理:统一转为小写(如"Python"和"python"视为相同)
    • 游戏分段:遇到"bullshit"时:
      • 当前游戏的不同单词数 = 集合current_words的大小
      • 重置集合开始新游戏
    • 分数化简:用最大公约数(GCD)化简总分/游戏次数

    4. 数据结构选择

    需求 选择 原因
    快速去重 unordered_set O(1)时间查询/插入
    大小写转换 transform 高效字符串处理
    单词匹配 正则表达式 精确提取字母组合

    5. 边界情况处理

    • 空输入:输出"0/1"
    • 连续BULLSHIT:忽略空游戏
    • 超大输入:流式处理避免内存溢出
    • 特殊字符:正则表达式自动过滤

    6. 复杂度分析

    • 时间复杂度:O(N) (N为总字符数)
      • 正则匹配:O(L)每行
      • 集合操作:O(1)每个单词
    • 空间复杂度:O(M) (M为单局最大不同单词数)

    7. 常见陷阱

    1. 大小写敏感(必须统一转小写)
    2. 分数未化简(如4/2应输出2/1)
    3. 标点符号粘连(如"hello,world"应识别为两个单词)

    标程

    #include <iostream>
    #include <string>
    #include <set>
    #include <algorithm>
    #include <vector>
    #include <cctype>
    
    using namespace std;
    
    // C++98 兼容的字符串分割函数
    vector<string> split_words(const string& line) {
        vector<string> words;
        string current_word;
        
        for (size_t i = 0; i < line.size(); ++i) {
            if (isalpha(line[i])) {
                current_word += tolower(line[i]);
            } else if (!current_word.empty()) {
                words.push_back(current_word);
                current_word.clear();
            }
        }
        
        if (!current_word.empty()) {
            words.push_back(current_word);
        }
        
        return words;
    }
    
    // C++98 兼容的最大公约数计算
    int gcd(int a, int b) {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
        
        set<string> current_words;
        int total_words = 0;
        int game_count = 0;
        string line;
        
        while (getline(cin, line)) {
            vector<string> words = split_words(line);
            
            for (size_t i = 0; i < words.size(); ++i) {
                string word = words[i];
                
                if (word == "bullshit") {
                    if (!current_words.empty()) {
                        total_words += current_words.size();
                        game_count++;
                        current_words.clear();
                    }
                } else {
                    current_words.insert(word);
                }
            }
        }
        
        if (game_count == 0) {
            cout << "0 / 1" << endl;
        } else {
            int common_divisor = gcd(total_words, game_count);
            cout << total_words / common_divisor << " / " 
                 << game_count / common_divisor << endl;
        }
        
        return 0;
    }
    • 1

    信息

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