// Řešení využívá datové struktury a algoritmy knihovny // STL v C++, často povolená a užitečná na soutěžích #include #include #include // dynamické pole #include // řetězce s proměnnou délkou #include #define MAX 1000001 using namespace std; int koren(const char* slovo, int delka) { int p = 1, i = 0, d = delka / 2; for (int z = 1; z < delka; z++) { if (slovo[z] == slovo[i % p]) // perioda funguje dále i++; else if (slovo[z] == slovo[0]) { p = z; i = 1; } else { p = z + 1; i = 0; } if (p > d) return delka; } return p; } int main(void) { int n = 0, dl = 0, soucet = 0, souv = 0; FILE *fin, *fout; vector koreny; // pole řetězců == kořenů char slovo[MAX]; fin = fopen("clanky.in", "r"); fscanf(fin, "%d", &n); for (int i = 0; i < n; i++) { fscanf(fin, "%d %s\n", &dl, slovo); slovo[koren(slovo,dl)] = 0; // uřízne zbytek slova po kořenu koreny.push_back(slovo); // vloží kořen do pole řetězců // nepamatujeme si celý vstup, ale pouze kořeny } fclose(fin); sort(koreny.begin(), koreny.end()); // setřídí kořeny soucet = n; for (int i = 1; i < n; i++) { if (koreny[i-1] == koreny[i]) { souv++; soucet += 2 * souv; // přičti 1 za každý stejný kořen dříve } else souv = 0; } fout = fopen("pocet.out", "w"); fprintf(fout, "%d\n", soucet); fclose(fout); return 0; }