/* * Copyright (C) 2018 Paweł Widera * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details: * http://www.gnu.org/licenses/gpl.html */ #include <iostream> #include <string> #include <vector> #include <unordered_set> using namespace std; #define DBG(key, value) cerr << key << " " << value << endl; const unordered_set<char> vowels = {'a', 'e', 'i', 'o', 'u', 'y'}; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string text; cin >> text; long long int n = text.size(); if (n < 3) { cout << 0 << endl; return 0; } vector<pair<long long int,long long int>> ranges; int vowel = 0; int consonant = 0; // find all difficult ranges for (int i = 0; i < n; ++i) { if (vowels.count(text[i])) { ++vowel; consonant = 0; } else { ++consonant; vowel = 0; } if (consonant >= 3 || vowel >= 3) { int length = max(consonant, vowel); int start = i - length + 1; if (!ranges.empty() && ranges.back().first == start) { ranges.pop_back(); } ranges.emplace_back(start, i + 1); } } int last = 0; // count all fragments around each range long long int counter = 0; for (auto range : ranges) { auto length = range.second - range.first; // fragments inside the range counter += (length - 2) * (length - 1) / 2 - 1; // fragments containing the range counter += (range.first - last + 1) * (n - range.second + 1); // fragment that begin/end within the range if (length > 3) { counter += (range.first - last) * (length - 3); counter += (n - range.second) * (length - 3); } // remember current end to avoid counting overlaps last = range.second - 2; } cout << counter << endl; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | /* * Copyright (C) 2018 Paweł Widera * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details: * http://www.gnu.org/licenses/gpl.html */ #include <iostream> #include <string> #include <vector> #include <unordered_set> using namespace std; #define DBG(key, value) cerr << key << " " << value << endl; const unordered_set<char> vowels = {'a', 'e', 'i', 'o', 'u', 'y'}; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string text; cin >> text; long long int n = text.size(); if (n < 3) { cout << 0 << endl; return 0; } vector<pair<long long int,long long int>> ranges; int vowel = 0; int consonant = 0; // find all difficult ranges for (int i = 0; i < n; ++i) { if (vowels.count(text[i])) { ++vowel; consonant = 0; } else { ++consonant; vowel = 0; } if (consonant >= 3 || vowel >= 3) { int length = max(consonant, vowel); int start = i - length + 1; if (!ranges.empty() && ranges.back().first == start) { ranges.pop_back(); } ranges.emplace_back(start, i + 1); } } int last = 0; // count all fragments around each range long long int counter = 0; for (auto range : ranges) { auto length = range.second - range.first; // fragments inside the range counter += (length - 2) * (length - 1) / 2 - 1; // fragments containing the range counter += (range.first - last + 1) * (n - range.second + 1); // fragment that begin/end within the range if (length > 3) { counter += (range.first - last) * (length - 3); counter += (n - range.second) * (length - 3); } // remember current end to avoid counting overlaps last = range.second - 2; } cout << counter << endl; return 0; } |