#include <bits/stdc++.h> using namespace std; long long glob = 0; vector <long long> Poz; vector <vector <int> > Cyfry; vector <int> Dlugosc; // ile zer wiodacych ma ta liczba long long Wynik = 0; long long WczytajInt(){ auto r = 0; auto c = getchar_unlocked(); while (c < '0') c = getchar_unlocked(); while (c >= '0') { r = r * 10 + c - '0'; c = getchar_unlocked(); } return r; } void Podziel(long long X){ vector <int> Res; while (X > 0){ Res.push_back(X%10); X /= 10; } reverse(Res.rbegin(), Res.rend()); Cyfry.push_back(Res); } int ZaleznoscPrefiksu(long long X){ int pop = -1; // czy prefiks jest ściśle większy bool same9 = true; for (int i = 0; i < Cyfry[X].size(); i++){ if (Cyfry[X][i] > Cyfry[X-1][i]){ return 1; // prefiks wiekszy } else if (Cyfry[X][i] < Cyfry[X-1][i]){ return 2; // prefiks mniejszy } } return 0; // caly prefiks identyczny } bool CzySame(long long X){ // czy same 9 w dalszym zapisie poprzednika int Dlug= Cyfry[X].size(); for (int i = Dlug; i < Cyfry[X-1].size(); i++){ if (Cyfry[X-1][i] != 9){ return false; } } return true; } void DopchnijDoPrefiksu(long long X, int dod){ int DlugoscPref = Cyfry[X].size(); int IleDodac = Dlugosc[X-1] - DlugoscPref + dod; // tyle dodac zer for (int i = DlugoscPref; i < min(DlugoscPref + IleDodac, 15); i++){ Cyfry[X].push_back(0); } Dlugosc[X] = Dlugosc[X-1] + dod; // 20 cyfr prefiksu wlasciwego, dalej zera } void Przeanalizuj(long long X){ Wynik -= Cyfry[X].size(); if (Cyfry[X].size() > Dlugosc[X-1]){ Dlugosc[X] = Cyfry[X].size(); } else{ int Typ = ZaleznoscPrefiksu(X); if (Typ == 0){ bool CzySame9 = CzySame(X); if (CzySame9){ DopchnijDoPrefiksu(X, 1); } else{ bool dod = true; for (int i = Cyfry[X-1].size()-1; i >= Cyfry[X].size(); i--){ if (Cyfry[X-1][i] == 9 && dod){ Cyfry[X-1][i] = 0; dod = true; } else if (dod){ Cyfry[X-1][i]++; dod = false; } if (!dod){ break; } } for (int i = Cyfry[X].size(); i < Cyfry[X-1].size(); i++){ Cyfry[X].push_back(Cyfry[X-1][i]); } Dlugosc[X] = Dlugosc[X-1]; } } if (Typ == 2){ // mam scisle mniejszy prefiks DopchnijDoPrefiksu(X, 1); } else if (Typ == 1){ // prefiks scisle wiekszy DopchnijDoPrefiksu(X, 0); } } Wynik += Dlugosc[X]; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int N = WczytajInt(); Poz.push_back(1); for (int i = 1; i < 10; i++){ Poz.push_back(Poz[i-1]*10); } for (int i = 0; i < N; i++){ long long x = WczytajInt(); Podziel(x); } Dlugosc.resize(N); Dlugosc[0] = Cyfry[0].size(); for (int i = 1; i < N; i++){ Przeanalizuj(i); } cout << Wynik << "\n"; }
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 | #include <bits/stdc++.h> using namespace std; long long glob = 0; vector <long long> Poz; vector <vector <int> > Cyfry; vector <int> Dlugosc; // ile zer wiodacych ma ta liczba long long Wynik = 0; long long WczytajInt(){ auto r = 0; auto c = getchar_unlocked(); while (c < '0') c = getchar_unlocked(); while (c >= '0') { r = r * 10 + c - '0'; c = getchar_unlocked(); } return r; } void Podziel(long long X){ vector <int> Res; while (X > 0){ Res.push_back(X%10); X /= 10; } reverse(Res.rbegin(), Res.rend()); Cyfry.push_back(Res); } int ZaleznoscPrefiksu(long long X){ int pop = -1; // czy prefiks jest ściśle większy bool same9 = true; for (int i = 0; i < Cyfry[X].size(); i++){ if (Cyfry[X][i] > Cyfry[X-1][i]){ return 1; // prefiks wiekszy } else if (Cyfry[X][i] < Cyfry[X-1][i]){ return 2; // prefiks mniejszy } } return 0; // caly prefiks identyczny } bool CzySame(long long X){ // czy same 9 w dalszym zapisie poprzednika int Dlug= Cyfry[X].size(); for (int i = Dlug; i < Cyfry[X-1].size(); i++){ if (Cyfry[X-1][i] != 9){ return false; } } return true; } void DopchnijDoPrefiksu(long long X, int dod){ int DlugoscPref = Cyfry[X].size(); int IleDodac = Dlugosc[X-1] - DlugoscPref + dod; // tyle dodac zer for (int i = DlugoscPref; i < min(DlugoscPref + IleDodac, 15); i++){ Cyfry[X].push_back(0); } Dlugosc[X] = Dlugosc[X-1] + dod; // 20 cyfr prefiksu wlasciwego, dalej zera } void Przeanalizuj(long long X){ Wynik -= Cyfry[X].size(); if (Cyfry[X].size() > Dlugosc[X-1]){ Dlugosc[X] = Cyfry[X].size(); } else{ int Typ = ZaleznoscPrefiksu(X); if (Typ == 0){ bool CzySame9 = CzySame(X); if (CzySame9){ DopchnijDoPrefiksu(X, 1); } else{ bool dod = true; for (int i = Cyfry[X-1].size()-1; i >= Cyfry[X].size(); i--){ if (Cyfry[X-1][i] == 9 && dod){ Cyfry[X-1][i] = 0; dod = true; } else if (dod){ Cyfry[X-1][i]++; dod = false; } if (!dod){ break; } } for (int i = Cyfry[X].size(); i < Cyfry[X-1].size(); i++){ Cyfry[X].push_back(Cyfry[X-1][i]); } Dlugosc[X] = Dlugosc[X-1]; } } if (Typ == 2){ // mam scisle mniejszy prefiks DopchnijDoPrefiksu(X, 1); } else if (Typ == 1){ // prefiks scisle wiekszy DopchnijDoPrefiksu(X, 0); } } Wynik += Dlugosc[X]; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int N = WczytajInt(); Poz.push_back(1); for (int i = 1; i < 10; i++){ Poz.push_back(Poz[i-1]*10); } for (int i = 0; i < N; i++){ long long x = WczytajInt(); Podziel(x); } Dlugosc.resize(N); Dlugosc[0] = Cyfry[0].size(); for (int i = 1; i < N; i++){ Przeanalizuj(i); } cout << Wynik << "\n"; } |