1 条题解
-
0
方法思路
我们可以通过优化算法来提高效率:
- 不需要每次都重新计算整个子串的权值,可以使用前缀和来快速计算
- 维护两个前缀和数组:一个记录元音字母数量,一个记录辅音字母数量
- 对于每个切割点,可以O(1)时间计算左右两部分的权值
- 避免创建子字符串,减少内存操作
代码实现
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
- 上传者