#include <iostream> using namespace std; // -------- STOS struct elem{ unsigned int dane; // miejsce na przechowywanie danych zapamiętanych w danym elemencie elem* nast; // wskaźnik na kolejny element stosu (właściwie to poprzedni dodany) }; void push (elem* &stos, int x) { elem *nowy = new elem; // przydzielenie pamięci dla nowego elementu nowy->dane = x; // wczytanie danych do nowego elementu nowy->nast = stos; // wskaźnik nowego (ostatniego) elementu wskazuje na poprzedni (przedostatni) element stos = nowy; // wskaźnik stosu pokazuje na nowy (ostatni) element stosu, czyli jedyny, do którego jest bezpośredni dostęp } int pop (elem* &stos) { if (stos) // sprawdzenie, czy stos nie jest pusty { elem *temp = stos; // wprowadzenie pomocniczego wskaźnika int doZwrotu = temp->dane; // zapamiętanie w zmiennej lokalnej, co trzeba będzie zwrócić stos = stos->nast; // wskaźnik stosu przesuwamy, by pokazywał na przedostatni element (czyli ten, który zostanie ostatnim po usunięciu obecnego ostatniego) delete temp; // usunięcie pamięci przydzielonej na element return doZwrotu; // zwraca wartość z usuniętego elementu } return 0; // zwraca 0, gdy stos jest pusty } int top (elem* stos) { if (stos) // sprawdzenie, czy stos nie jest pusty { return stos->dane; // zwraca wartość z ostatniego elementu // nic innego nie jest modyfikowane! } return 0; // zwraca 0, gdy stos jest pusty // w skrócie funkcja topEl może wyglądać tak, jak poniżej // return (stos ? stos->dane : 0); } bool isEmpty(elem* stos) { if(stos) // sprawdzenie, czy stos nie jest pusty return false; // zwraca 0, jeśli stos nie jest pusty else return true; // zwraca 1, jeśli stos jest pusty // w skrócie funkcja isEmpty może wyglądać tak, jak poniżej // return (stos ? false : true); } // -------- STOS int main() { elem *stosGrup = nullptr; char grupa = 0; int gdzieJestem = 0; // do 200 000 bool poprzedni = true; // spolgloska char zyczenia[200001]; cin >> zyczenia; // ------------ IDENTYFIKACJA GRUP while(zyczenia[gdzieJestem]) { if(zyczenia[gdzieJestem] == 97 || zyczenia[gdzieJestem] == 101 || zyczenia[gdzieJestem] == 105 || zyczenia[gdzieJestem] == 111 || zyczenia[gdzieJestem] == 117 || zyczenia[gdzieJestem] == 121) { if(poprzedni) grupa = 1; // pierwsza samogloska else grupa++; // kolejna samogloska poprzedni = false; } else { if (poprzedni) grupa++; // kolejna spolgloska else grupa = 1; // pierwsza spogloska poprzedni = true; } if(grupa == 3) { // ADD TO SEKWENCJA push(stosGrup, gdzieJestem - 2); gdzieJestem -= 2; // bo sekwencje moga sie zazebiac grupa = 0; } gdzieJestem++; } // ---------- ANALIZA GRUP // gdzieJestem - dlugosc zyczen if(isEmpty(stosGrup)) // nie znaleziono sekwencji { cout << 0; return 0; } // znaleziono co najmniej jedna sekwencje // ostatnia (pierwsza od konca) sekwencja int aktualnaSekwencja = pop(stosGrup); int przedSekwencja = aktualnaSekwencja; int poSekwencji = gdzieJestem - aktualnaSekwencja - 3; unsigned long long wzor = 1 + przedSekwencja + przedSekwencja * poSekwencji + poSekwencji; // pobranie kolejnych elementów ze stosu, aż do całkowitego opróżnienia while(!isEmpty(stosGrup)) // dopóki stos nie jest pusty { gdzieJestem = aktualnaSekwencja; // ustawienie dlugosci na poprzednio policzona sekwencje aktualnaSekwencja = pop(stosGrup); przedSekwencja = aktualnaSekwencja; poSekwencji = gdzieJestem - aktualnaSekwencja - 3; if (poSekwencji == 0) { // sekwencja xxxyyy czyli grupa spolglowek i grupa samoglosek obok siebie poSekwencji = 2; wzor = wzor + 1 + przedSekwencja + przedSekwencja * (poSekwencji) + poSekwencji; } else { if(poSekwencji < 0) // jeśli sekwencje się zazębiają wzor = wzor + 1 + przedSekwencja; else // jeśli sekwencje się nie zazębiają wzor = wzor + 1 + przedSekwencja + przedSekwencja * (poSekwencji + 2) + poSekwencji + 2; } } cout << wzor; 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 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 | #include <iostream> using namespace std; // -------- STOS struct elem{ unsigned int dane; // miejsce na przechowywanie danych zapamiętanych w danym elemencie elem* nast; // wskaźnik na kolejny element stosu (właściwie to poprzedni dodany) }; void push (elem* &stos, int x) { elem *nowy = new elem; // przydzielenie pamięci dla nowego elementu nowy->dane = x; // wczytanie danych do nowego elementu nowy->nast = stos; // wskaźnik nowego (ostatniego) elementu wskazuje na poprzedni (przedostatni) element stos = nowy; // wskaźnik stosu pokazuje na nowy (ostatni) element stosu, czyli jedyny, do którego jest bezpośredni dostęp } int pop (elem* &stos) { if (stos) // sprawdzenie, czy stos nie jest pusty { elem *temp = stos; // wprowadzenie pomocniczego wskaźnika int doZwrotu = temp->dane; // zapamiętanie w zmiennej lokalnej, co trzeba będzie zwrócić stos = stos->nast; // wskaźnik stosu przesuwamy, by pokazywał na przedostatni element (czyli ten, który zostanie ostatnim po usunięciu obecnego ostatniego) delete temp; // usunięcie pamięci przydzielonej na element return doZwrotu; // zwraca wartość z usuniętego elementu } return 0; // zwraca 0, gdy stos jest pusty } int top (elem* stos) { if (stos) // sprawdzenie, czy stos nie jest pusty { return stos->dane; // zwraca wartość z ostatniego elementu // nic innego nie jest modyfikowane! } return 0; // zwraca 0, gdy stos jest pusty // w skrócie funkcja topEl może wyglądać tak, jak poniżej // return (stos ? stos->dane : 0); } bool isEmpty(elem* stos) { if(stos) // sprawdzenie, czy stos nie jest pusty return false; // zwraca 0, jeśli stos nie jest pusty else return true; // zwraca 1, jeśli stos jest pusty // w skrócie funkcja isEmpty może wyglądać tak, jak poniżej // return (stos ? false : true); } // -------- STOS int main() { elem *stosGrup = nullptr; char grupa = 0; int gdzieJestem = 0; // do 200 000 bool poprzedni = true; // spolgloska char zyczenia[200001]; cin >> zyczenia; // ------------ IDENTYFIKACJA GRUP while(zyczenia[gdzieJestem]) { if(zyczenia[gdzieJestem] == 97 || zyczenia[gdzieJestem] == 101 || zyczenia[gdzieJestem] == 105 || zyczenia[gdzieJestem] == 111 || zyczenia[gdzieJestem] == 117 || zyczenia[gdzieJestem] == 121) { if(poprzedni) grupa = 1; // pierwsza samogloska else grupa++; // kolejna samogloska poprzedni = false; } else { if (poprzedni) grupa++; // kolejna spolgloska else grupa = 1; // pierwsza spogloska poprzedni = true; } if(grupa == 3) { // ADD TO SEKWENCJA push(stosGrup, gdzieJestem - 2); gdzieJestem -= 2; // bo sekwencje moga sie zazebiac grupa = 0; } gdzieJestem++; } // ---------- ANALIZA GRUP // gdzieJestem - dlugosc zyczen if(isEmpty(stosGrup)) // nie znaleziono sekwencji { cout << 0; return 0; } // znaleziono co najmniej jedna sekwencje // ostatnia (pierwsza od konca) sekwencja int aktualnaSekwencja = pop(stosGrup); int przedSekwencja = aktualnaSekwencja; int poSekwencji = gdzieJestem - aktualnaSekwencja - 3; unsigned long long wzor = 1 + przedSekwencja + przedSekwencja * poSekwencji + poSekwencji; // pobranie kolejnych elementów ze stosu, aż do całkowitego opróżnienia while(!isEmpty(stosGrup)) // dopóki stos nie jest pusty { gdzieJestem = aktualnaSekwencja; // ustawienie dlugosci na poprzednio policzona sekwencje aktualnaSekwencja = pop(stosGrup); przedSekwencja = aktualnaSekwencja; poSekwencji = gdzieJestem - aktualnaSekwencja - 3; if (poSekwencji == 0) { // sekwencja xxxyyy czyli grupa spolglowek i grupa samoglosek obok siebie poSekwencji = 2; wzor = wzor + 1 + przedSekwencja + przedSekwencja * (poSekwencji) + poSekwencji; } else { if(poSekwencji < 0) // jeśli sekwencje się zazębiają wzor = wzor + 1 + przedSekwencja; else // jeśli sekwencje się nie zazębiają wzor = wzor + 1 + przedSekwencja + przedSekwencja * (poSekwencji + 2) + poSekwencji + 2; } } cout << wzor; return 0; } |