#include <vector> #include <iostream> #include <chrono> #include <array> #define MAX_WORD 300000 #define NUMBER_OF_POSSIBLE_LETTERS 3 class Timer { private: std::chrono::steady_clock::time_point start; public: Timer() { start = std::chrono::steady_clock::now(); } void tick(std::string description) { std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); std::cout << "\n" << description << ": " << (now - start).count() << "ns"; start = now; } }; std::vector<char> getInput() { std::vector<char> result; result.reserve(MAX_WORD); while (true) { char c = getchar(); if (c < 'a') break; result.emplace_back(c); } return result; } void prepareInputOutput() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); } class WordContents { public: std::array<int, NUMBER_OF_POSSIBLE_LETTERS> count; void reset() { for (int i = 0; i < NUMBER_OF_POSSIBLE_LETTERS; i++) count[i] = 0; } bool isWordBalanced() { int currentMaxNumber = count[0]; for (int i = 1; i < NUMBER_OF_POSSIBLE_LETTERS; i++) { if (count[i] == 0) { continue; } if (count[i] != currentMaxNumber && currentMaxNumber == 0) { currentMaxNumber = count[i]; continue; } if (count[i] != currentMaxNumber && currentMaxNumber != 0) { return false; } } return true; } bool isWordBalanced2Zeros() { return true; } bool isWordBalanced1Zero(const int& indexOfFirstLetter, const int& indexOfSecondLetter) { return count[indexOfFirstLetter] == count[indexOfSecondLetter]; } bool isWordBalancedNoZeros() { return count[0] == count[1] && count[1] == count[2]; } }; int getThirdLetterIndex(const int& indexOfFirstLetter, const int& indexOfSecondLetter) { if (indexOfFirstLetter == 0 && indexOfSecondLetter == 1) return 2; if (indexOfFirstLetter == 0 && indexOfSecondLetter == 2) return 1; if (indexOfFirstLetter == 1 && indexOfSecondLetter == 2) return 0; if (indexOfFirstLetter == 1 && indexOfSecondLetter == 0) return 2; if (indexOfFirstLetter == 2 && indexOfSecondLetter == 0) return 1; if (indexOfFirstLetter == 2 && indexOfSecondLetter == 1) return 0; } long long solve1(const std::vector<char>& input) { long long result = 0; WordContents contents = WordContents(); for (int i = 0; i < input.size(); i++) { int j = i - 1; // first letter int firstLetterIndex = input[i] - 'a'; contents.count[firstLetterIndex]++; result++; // 2 zeros while (input[j] == input[i] && j >= 0) { contents.count[firstLetterIndex]++; result++; j--; } int secondLetterIndex = input[j] - 'a'; int thirdLetterIndex = getThirdLetterIndex(firstLetterIndex, secondLetterIndex); // 1 zero while (input[j] - 'a' != thirdLetterIndex && j >= 0) { contents.count[input[j] - 'a']++; result += contents.isWordBalanced1Zero(firstLetterIndex, secondLetterIndex); j--; } // no zeros while (j >= 0) { contents.count[input[j] - 'a']++; result += contents.isWordBalancedNoZeros(); j--; } // reset contents.reset(); } return result; } long long solve0(const std::vector<char>& input) { long long result = 0; WordContents contents = WordContents(); for (int i = 0; i < input.size(); i++) { for (int j = i; j >= 0; j--) { contents.count[input[j] - 'a']++; if (contents.isWordBalanced()) result++; } contents.reset(); } return result; } int main() { //Timer timer; prepareInputOutput(); //timer.tick("preprate IO"); std::vector<char> input = getInput(); //timer.tick("getInput"); std::cout << solve1(input); //timer.tick("solve1"); }
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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | #include <vector> #include <iostream> #include <chrono> #include <array> #define MAX_WORD 300000 #define NUMBER_OF_POSSIBLE_LETTERS 3 class Timer { private: std::chrono::steady_clock::time_point start; public: Timer() { start = std::chrono::steady_clock::now(); } void tick(std::string description) { std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); std::cout << "\n" << description << ": " << (now - start).count() << "ns"; start = now; } }; std::vector<char> getInput() { std::vector<char> result; result.reserve(MAX_WORD); while (true) { char c = getchar(); if (c < 'a') break; result.emplace_back(c); } return result; } void prepareInputOutput() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); } class WordContents { public: std::array<int, NUMBER_OF_POSSIBLE_LETTERS> count; void reset() { for (int i = 0; i < NUMBER_OF_POSSIBLE_LETTERS; i++) count[i] = 0; } bool isWordBalanced() { int currentMaxNumber = count[0]; for (int i = 1; i < NUMBER_OF_POSSIBLE_LETTERS; i++) { if (count[i] == 0) { continue; } if (count[i] != currentMaxNumber && currentMaxNumber == 0) { currentMaxNumber = count[i]; continue; } if (count[i] != currentMaxNumber && currentMaxNumber != 0) { return false; } } return true; } bool isWordBalanced2Zeros() { return true; } bool isWordBalanced1Zero(const int& indexOfFirstLetter, const int& indexOfSecondLetter) { return count[indexOfFirstLetter] == count[indexOfSecondLetter]; } bool isWordBalancedNoZeros() { return count[0] == count[1] && count[1] == count[2]; } }; int getThirdLetterIndex(const int& indexOfFirstLetter, const int& indexOfSecondLetter) { if (indexOfFirstLetter == 0 && indexOfSecondLetter == 1) return 2; if (indexOfFirstLetter == 0 && indexOfSecondLetter == 2) return 1; if (indexOfFirstLetter == 1 && indexOfSecondLetter == 2) return 0; if (indexOfFirstLetter == 1 && indexOfSecondLetter == 0) return 2; if (indexOfFirstLetter == 2 && indexOfSecondLetter == 0) return 1; if (indexOfFirstLetter == 2 && indexOfSecondLetter == 1) return 0; } long long solve1(const std::vector<char>& input) { long long result = 0; WordContents contents = WordContents(); for (int i = 0; i < input.size(); i++) { int j = i - 1; // first letter int firstLetterIndex = input[i] - 'a'; contents.count[firstLetterIndex]++; result++; // 2 zeros while (input[j] == input[i] && j >= 0) { contents.count[firstLetterIndex]++; result++; j--; } int secondLetterIndex = input[j] - 'a'; int thirdLetterIndex = getThirdLetterIndex(firstLetterIndex, secondLetterIndex); // 1 zero while (input[j] - 'a' != thirdLetterIndex && j >= 0) { contents.count[input[j] - 'a']++; result += contents.isWordBalanced1Zero(firstLetterIndex, secondLetterIndex); j--; } // no zeros while (j >= 0) { contents.count[input[j] - 'a']++; result += contents.isWordBalancedNoZeros(); j--; } // reset contents.reset(); } return result; } long long solve0(const std::vector<char>& input) { long long result = 0; WordContents contents = WordContents(); for (int i = 0; i < input.size(); i++) { for (int j = i; j >= 0; j--) { contents.count[input[j] - 'a']++; if (contents.isWordBalanced()) result++; } contents.reset(); } return result; } int main() { //Timer timer; prepareInputOutput(); //timer.tick("preprate IO"); std::vector<char> input = getInput(); //timer.tick("getInput"); std::cout << solve1(input); //timer.tick("solve1"); } |