#include <stdio.h> #include <string.h> char slowo[200010]; // nie znamy dlugosci, nie da sie tego zrobic bez wczytania slowa dwa razy // ok, no to trafilismy na 3 lub wiecej wspolglosek lub samoglosek, no i lecim z koksem long int dodajNowe(long int przed, long int takichsamych, long int po) { long int rv = 0; // spotkalismy paczke. // no to bierzemy wszystki podzbiory paczki, takie co sie zaczynaja w paczce i koncza w paczce // to sa te, ktore zaczynaja sie i koncza wewnatrz tego fragmentu rv += (takichsamych-2)*(takichsamych-1)/2; // to jest ilos fragmentow ktore zaczanaja sie na poczatku i konca wewnatrz fragmentu, lub zaczynaja wewnatrz fragmentu i ciagna do konca int fragmentydo = takichsamych - 2; // to jest cos co zaczyna sie wewnatrz fragmentu i ma nie pusta kontunacje po nim rv += fragmentydo * po; // jesli po naszmy slowie cos jest to mozemy to dodac ale juz do konca i przynajmniej jedna literke // to jest cos co konczy sie wewnatrz fragmentu i ma nie pusty prefix rv += fragmentydo * przed; // no i jeszcze te, ktore zawieraja cos przed fragmentem + fragment + cos za fragmentem rv += przed * po; return rv; } int main() { int i; int poprzednia = -1; int dlugosc; int dlugosctakichsamych = 0; int s[256]; long int wynik = 0; int indeks_ostatniej = 0; memset(s, 0, sizeof(s)); s['a'] = 1; s['e'] = 1; s['i'] = 1; s['o'] = 1; s['u'] = 1; s['y'] = 1; fgets(slowo, 200010, stdin); // dodamy jeszcze 10 bajtow tak na szczescie (wystarczylo by dodac jeden) dlugosc = strlen(slowo); // pierwsze przejscie po slowie while (dlugosc > 0 && (slowo[dlugosc-1]<'a' || slowo[dlugosc-1]>'z')) { dlugosc--; } wynik = 0; for(i=0;i<dlugosc;i++) { if (s[(unsigned char)slowo[i]]==poprzednia) { dlugosctakichsamych++; } else { if (dlugosctakichsamych >= 3) { wynik += dodajNowe(i-dlugosctakichsamych - indeks_ostatniej, dlugosctakichsamych, dlugosc-i); indeks_ostatniej = i - 2; // OK, teraz chodzi o to, ze poprzednie testy juz wliczyly to i wszystkie mozliwosci za soba, // no to jakby bylokujemy od tego miejsca } dlugosctakichsamych = 1; } poprzednia = s[(unsigned char)slowo[i]]; } if (dlugosctakichsamych >= 3) { wynik += dodajNowe(i-dlugosctakichsamych - indeks_ostatniej, dlugosctakichsamych, dlugosc-i); } printf("%ld\n", wynik); }
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 | #include <stdio.h> #include <string.h> char slowo[200010]; // nie znamy dlugosci, nie da sie tego zrobic bez wczytania slowa dwa razy // ok, no to trafilismy na 3 lub wiecej wspolglosek lub samoglosek, no i lecim z koksem long int dodajNowe(long int przed, long int takichsamych, long int po) { long int rv = 0; // spotkalismy paczke. // no to bierzemy wszystki podzbiory paczki, takie co sie zaczynaja w paczce i koncza w paczce // to sa te, ktore zaczynaja sie i koncza wewnatrz tego fragmentu rv += (takichsamych-2)*(takichsamych-1)/2; // to jest ilos fragmentow ktore zaczanaja sie na poczatku i konca wewnatrz fragmentu, lub zaczynaja wewnatrz fragmentu i ciagna do konca int fragmentydo = takichsamych - 2; // to jest cos co zaczyna sie wewnatrz fragmentu i ma nie pusta kontunacje po nim rv += fragmentydo * po; // jesli po naszmy slowie cos jest to mozemy to dodac ale juz do konca i przynajmniej jedna literke // to jest cos co konczy sie wewnatrz fragmentu i ma nie pusty prefix rv += fragmentydo * przed; // no i jeszcze te, ktore zawieraja cos przed fragmentem + fragment + cos za fragmentem rv += przed * po; return rv; } int main() { int i; int poprzednia = -1; int dlugosc; int dlugosctakichsamych = 0; int s[256]; long int wynik = 0; int indeks_ostatniej = 0; memset(s, 0, sizeof(s)); s['a'] = 1; s['e'] = 1; s['i'] = 1; s['o'] = 1; s['u'] = 1; s['y'] = 1; fgets(slowo, 200010, stdin); // dodamy jeszcze 10 bajtow tak na szczescie (wystarczylo by dodac jeden) dlugosc = strlen(slowo); // pierwsze przejscie po slowie while (dlugosc > 0 && (slowo[dlugosc-1]<'a' || slowo[dlugosc-1]>'z')) { dlugosc--; } wynik = 0; for(i=0;i<dlugosc;i++) { if (s[(unsigned char)slowo[i]]==poprzednia) { dlugosctakichsamych++; } else { if (dlugosctakichsamych >= 3) { wynik += dodajNowe(i-dlugosctakichsamych - indeks_ostatniej, dlugosctakichsamych, dlugosc-i); indeks_ostatniej = i - 2; // OK, teraz chodzi o to, ze poprzednie testy juz wliczyly to i wszystkie mozliwosci za soba, // no to jakby bylokujemy od tego miejsca } dlugosctakichsamych = 1; } poprzednia = s[(unsigned char)slowo[i]]; } if (dlugosctakichsamych >= 3) { wynik += dodajNowe(i-dlugosctakichsamych - indeks_ostatniej, dlugosctakichsamych, dlugosc-i); } printf("%ld\n", wynik); } |