1 条题解

  • 0
    @ 2025-5-28 10:28:29

    题目分析

    本题要求实现一个文本缩写生成器,能够从输入文本中找出最优的缩写方案。缩写需要满足以下条件:

    1. 缩写由连续单词的首字母组成
    2. 缩写必须至少包含2个字母
    3. 缩写不能与文本中的任何单词相同
    4. 缩写必须唯一对应一组连续的单词
    5. 最优缩写应能节省最多的字符(即原单词总长度 - 缩写长度)

    解题思路

    1. 文本预处理

      • 提取所有单词(仅包含字母字符)
      • 转换为小写形式统一处理
      • 统计每个单词的出现频率
    2. 候选缩写生成

      • 遍历所有可能的连续单词组合
      • 生成由这些单词首字母组成的缩写
      • 计算每个缩写能节省的字符数(原单词总长度 - 缩写长度)
    3. 有效性检查

      • 检查缩写是否与已有单词冲突
      • 确保缩写唯一对应一组连续单词
      • 过滤掉不符合条件的候选缩写
    4. 最优选择

      • 在所有有效缩写中选择节省字符最多的方案
      • 如果有多个最优解,选择最先出现的

    完整代码

    #include <iostream>
    #include <vector>
    #include <string>
    #include <map>
    #include <cctype>
    #include <algorithm>
    
    using namespace std;
    
    vector<string> extractWords(const string& text) {
        vector<string> words;
        string current;
        for (size_t i = 0; i < text.size(); ++i) {
            if (isalpha(text[i])) {
                current += tolower(text[i]);
            } else if (!current.empty()) {
                words.push_back(current);
                current.clear();
            }
        }
        if (!current.empty()) {
            words.push_back(current);
        }
        return words;
    }
    
    vector<pair<string, int> > generateCandidates(const vector<string>& words) {
        vector<pair<string, int> > candidates;
        for (size_t i = 0; i < words.size(); ++i) {
            string abbr;
            int len = 0;
            for (size_t j = i; j < words.size(); ++j) {
                abbr += words[j][0];
                len += words[j].size();
                if (abbr.size() >= 2) { // Only consider abbreviations of 2+ letters
                    candidates.push_back(make_pair(abbr, len - abbr.size()));
                }
            }
        }
        return candidates;
    }
    
    bool isUnambiguous(const string& abbr, const vector<string>& words, const map<string, int>& wordCount) {
        // Check if abbr appears as a word
        string lowerAbbr;
        for (size_t i = 0; i < abbr.size(); ++i) {
            lowerAbbr += tolower(abbr[i]);
        }
        if (wordCount.find(lowerAbbr) != wordCount.end()) {
            return false;
        }
    
        // Check if abbr corresponds to exactly one sequence
        int matchCount = 0;
        for (size_t i = 0; i + abbr.size() <= words.size(); ++i) {
            bool match = true;
            for (size_t j = 0; j < abbr.size(); ++j) {
                if (tolower(abbr[j]) != tolower(words[i+j][0])) {
                    match = false;
                    break;
                }
            }
            if (match) {
                matchCount++;
                if (matchCount > 1) {
                    return false;
                }
            }
        }
        return matchCount == 1;
    }
    
    pair<int, string> findBestAbbreviation(const string& text) {
        vector<string> words = extractWords(text);
        map<string, int> wordCount;
        for (size_t i = 0; i < words.size(); ++i) {
            wordCount[words[i]]++;
        }
    
        vector<pair<string, int> > candidates = generateCandidates(words);
        int maxEffect = 0;
        string bestAbbr;
    
        for (size_t i = 0; i < candidates.size(); ++i) {
            const string& abbr = candidates[i].first;
            int effect = candidates[i].second;
            if (effect > maxEffect && isUnambiguous(abbr, words, wordCount)) {
                maxEffect = effect;
                bestAbbr = abbr;
            }
        }
    
        return make_pair(maxEffect, bestAbbr);
    }
    
    int main() {
        string text;
        string line;
        while (getline(cin, line)) {
            text += line + "\n";
        }
    
        pair<int, string> result = findBestAbbreviation(text);
        if (result.first > 0) {
            cout << result.first << endl;
            cout << result.second << endl;
        } else {
            cout << "0" << endl;
        }
    
        return 0;
    }
    
    • 1

    信息

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