/*
* 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; } |
English