1 条题解

  • 0
    @ 2025-4-9 22:24:22

    题意分析

    异位词(anagram)是指一个单词的字母重新排列后能形成另一个单词(例如 "occurs" 和 "succor")。异位词距离定义为:为了使两个单词的剩余部分成为异位词,需要移除的最小字母数量。具体规则:

    • 两个单词的字母频率必须完全一致才能成为异位词(例如 "dear" 和 "dared" 不是异位词,因为 'd' 的频率不同)。
    • 距离计算公式:设单词 A 和 B 的长度分别为 lenA \text{len}_A lenB \text{len}_B ,最大匹配部分的长度是所有字母中最小频率之和(即 $ \text{sum\_min} = \sum_{i=a}^{z} \min(\text{freq}_A(i), \text{freq}_B(i)) $)。则异位词距离 $ d = \text{len}_A + \text{len}_B - 2 \times \text{sum\_min} $。
      • 示例:"sleep" (长度5) 和 "leap" (长度4),最小频率和:l:1, e:1, p:1(sum_min=3),距离=5+4-2×3=3。
      • 极端情况:若单词无共同字母(如 "dog" 和 "cat"),sum_min=0,距离=3+3-0=6。

    代码示例

    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    int main() {
        int N;
        cin >> N;
        cin.ignore(); // 忽略换行符,因为后面用 getline
        for (int i = 1; i <= N; i++) {
            string word1, word2;
            getline(cin, word1); // 读一行,可能空
            getline(cin, word2);
            
            int len1 = word1.length();
            int len2 = word2.length();
            
            // 初始化频率数组
            vector<int> freq1(26, 0);
            vector<int> freq2(26, 0);
            
            // 计算 word1 频率
            for (char c : word1) {
                if (c >= 'a' && c <= 'z') {
                    freq1[c - 'a']++;
                }
            }
            
            // 同样为 word2
            for (char c : word2) {
                if (c >= 'a' && c <= 'z') {
                    freq2[c - 'a']++;
                }
            }
            
            // 计算 sum of min frequencies
            int sum_min = 0;
            for (int j = 0; j < 26; j++) {
                sum_min += min(freq1[j], freq2[j]);
            }
            
            // 计算距离
            int distance = len1 + len2 - 2 * sum_min;
            
            // 输出
            cout << "Case #" << i << ": " << distance << endl;
        }
        
        return 0;
    }
    

    解题思路

    1. 核心逻辑
      • 异位词要求字母频率一致。因此,计算每个单词的字母频率(26 个小写字母)。
      • 最大匹配长度 sum_min \text{sum\_min} 是所有字母在两个单词中最小频率之和(例如,字母 'e' 在 A 中出现 2 次,在 B 中出现 1 次,则贡献 min(2,1)=1)。
      • 距离 $ d = \text{len}_A + \text{len}_B - 2 \times \text{sum\_min} $。这是因为:
    • 移除的字母数 = (单词 A 中未匹配的字母) + (单词 B 中未匹配的字母)。
    • 未匹配部分长度 = lenAsum_min \text{len}_A - \text{sum\_min} + lenBsum_min \text{len}_B - \text{sum\_min}
    • 简化后得上述公式。
    1. 算法步骤

      • 读入数据:读整数 N N ,循环处理每个案例。每个案例读两个字符串(可能为空)。
      • 计算频率:为每个单词创建大小为 26 的频率数组(索引 0-25 对应 a-z)。遍历字符串,统计每个字母出现次数。
      • 计算 sum_min:遍历 26 个字母,累加 min(freqA[i],freqB[i]) \min(\text{freq}_A[i], \text{freq}_B[i])
      • 计算距离:$ d = \text{len}_A + \text{len}_B - 2 \times \text{sum\_min} $。
      • 输出结果:格式化输出 "Case #i: d"。
    2. 边界处理

      • 空单词:长度 0,频率全 0,sum_min=0,距离 = 0 + len - 0 = len(移除所有字母)。
      • 字母均为小写,无需大小写转换。
      • 性能:N N 最大 60,000,单词最长 45 字母(如 "pneumonoultramicroscopicsilicovolcanoconiosis"),频率计算 O(n),整体高效。
    3. 示例验证

      • Case #1: "crocus" 和 "succor"
    • 长度均 6,频率相同(c:2, r:1, o:1, u:1, s:1),sum_min=6。
    • d = 6 + 6 - 2×6 = 0。输出 0。
    • 1

    信息

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