1 条题解

  • 0
    @ 2025-7-14 17:26:40

    方法思路

    我们可以通过优化算法来提高效率:

    1. 不需要每次都重新计算整个子串的权值,可以使用前缀和来快速计算
    2. 维护两个前缀和数组:一个记录元音字母数量,一个记录辅音字母数量
    3. 对于每个切割点,可以O(1)时间计算左右两部分的权值
    4. 避免创建子字符串,减少内存操作

    代码实现

    Java
    import java.io.*;
    
    public class Main {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String s = br.readLine();
            System.out.println(countValidCuts(s));
        }
        
        public static int countValidCuts(String s) {
            int n = s.length();
            
            // 前缀和数组:vowelPrefix[i]表示前i个字符中元音的数量
            int[] vowelPrefix = new int[n + 1];
            int[] consonantPrefix = new int[n + 1];
            
            for (int i = 0; i < n; i++) {
                vowelPrefix[i + 1] = vowelPrefix[i];
                consonantPrefix[i + 1] = consonantPrefix[i];
                
                if (isVowel(s.charAt(i))) {
                    vowelPrefix[i + 1]++;
                } else {
                    consonantPrefix[i + 1]++;
                }
            }
            
            int count = 0;
            
            for (int i = 1; i < n; i++) {
                // 左侧子串:[0, i-1]
                int leftVowels = vowelPrefix[i];
                int leftConsonants = consonantPrefix[i];
                int leftWeight = Math.abs(leftVowels - leftConsonants);
                
                // 右侧子串:[i, n-1]
                int rightVowels = vowelPrefix[n] - vowelPrefix[i];
                int rightConsonants = consonantPrefix[n] - consonantPrefix[i];
                int rightWeight = Math.abs(rightVowels - rightConsonants);
                
                if (leftWeight == rightWeight) {
                    count++;
                }
            }
            
            return count;
        }
        
        private static boolean isVowel(char c) {
            return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
        }
    }
    
    
    Python
    def count_valid_cuts(s):
        n = len(s)
        
        # 前缀和数组
        vowel_prefix = [0] * (n + 1)
        consonant_prefix = [0] * (n + 1)
        
        for i in range(n):
            vowel_prefix[i + 1] = vowel_prefix[i]
            consonant_prefix[i + 1] = consonant_prefix[i]
            
            if s[i] in "aeiou":
                vowel_prefix[i + 1] += 1
            else:
                consonant_prefix[i + 1] += 1
        
        count = 0
        
        for i in range(1, n):
            # 左侧子串:[0, i-1]
            left_vowels = vowel_prefix[i]
            left_consonants = consonant_prefix[i]
            left_weight = abs(left_vowels - left_consonants)
            
            # 右侧子串:[i, n-1]
            right_vowels = vowel_prefix[n] - vowel_prefix[i]
            right_consonants = consonant_prefix[n] - consonant_prefix[i]
            right_weight = abs(right_vowels - right_consonants)
            
            if left_weight == right_weight:
                count += 1
        
        return count
    
    s = input().strip()
    print(count_valid_cuts(s))
    
    
    C++
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    using namespace std;
    
    bool isVowel(char c) {
        return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
    }
    
    int countValidCuts(const string& s) {
        int n = s.length();
        
        // 前缀和数组
        vector<int> vowelPrefix(n + 1, 0);
        vector<int> consonantPrefix(n + 1, 0);
        
        for (int i = 0; i < n; i++) {
            vowelPrefix[i + 1] = vowelPrefix[i];
            consonantPrefix[i + 1] = consonantPrefix[i];
            
            if (isVowel(s[i])) {
                vowelPrefix[i + 1]++;
            } else {
                consonantPrefix[i + 1]++;
            }
        }
        
        int count = 0;
        
        for (int i = 1; i < n; i++) {
            // 左侧子串:[0, i-1]
            int leftVowels = vowelPrefix[i];
            int leftConsonants = consonantPrefix[i];
            int leftWeight = abs(leftVowels - leftConsonants);
            
            // 右侧子串:[i, n-1]
            int rightVowels = vowelPrefix[n] - vowelPrefix[i];
            int rightConsonants = consonantPrefix[n] - consonantPrefix[i];
            int rightWeight = abs(rightVowels - rightConsonants);
            
            if (leftWeight == rightWeight) {
                count++;
            }
        }
        
        return count;
    }
    
    int main() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        
        string s;
        cin >> s;
        cout << countValidCuts(s) << endl;
        return 0;
    }
    
    
    • 1

    信息

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