#include <cstdio>
#include <cstdint>
#include <cmath>
using namespace std;
int b10l(int64_t x) {
int i = 1;
int64_t t = 10;
while (1) {
if (x < t) {
return i;
}
t *= 10;
++i;
}
}
const int MAX_LENGTH = 17;
const int MIN_LENGTH = 10;
struct extnum_t {
int64_t prefix;
int zeros;
};
void extnum_init(extnum_t& e, int64_t prefix, int zeros = 0) {
int plen = b10l(prefix);
if (plen + zeros <= MAX_LENGTH) {
e.prefix = prefix * (int64_t)pow(10LL, zeros);
e.zeros = 0;
}
else if (plen >= MIN_LENGTH) {
e.prefix = prefix / (int64_t)pow(10LL, plen - MIN_LENGTH);
e.zeros = zeros + plen - MIN_LENGTH;
}
else {
e.prefix = prefix * (int64_t)pow(10LL, MIN_LENGTH - plen);
e.zeros = zeros + MIN_LENGTH - plen;
}
}
bool is_prefix(int64_t what, int64_t of, int l1 = 0, int l2 = 0) {
if (!l1) {
l1 = b10l(what);
}
if (!l2) {
l2 = b10l(of);
}
if (l1 > l2) {
return false;
}
of /= (int64_t)pow(10, l2 - l1);
return what == of;
}
int extend(extnum_t& n, int64_t prefix) {
int l1 = b10l(n.prefix);
int l2 = b10l(prefix);
if (is_prefix(prefix, n.prefix, l2, l1)) {
int ret = n.zeros + l1 - l2;
if (n.zeros) {
return ret;
}
if (l1 == l2 || n.prefix % (int64_t)pow(10, l1 - l2) + 1 == (int64_t)pow(10, l1 - l2)) {
extnum_init(n, prefix, l1 - l2 + 1);
++ret;
}
else {
extnum_init(n, n.prefix + 1);
}
return ret;
}
if (l2 > l1) {
n.zeros = 0;
n.prefix = prefix;
return 0;
}
int ret = l1 - l2;
prefix *= (int64_t)pow(10LL, ret);
if (prefix > n.prefix) {
n.prefix = prefix;
ret += n.zeros;
}
else {
ret += n.zeros + 1;
extnum_init(n, prefix, n.zeros + 1);
}
return ret;
}
int main () {
int n;
scanf("%d", &n);
extnum_t last;
int64_t x;
scanf("%lld", &x);
extnum_init(last, x);
int64_t digits = 0;
for (int i = 1; i < n; ++i) {
int64_t x;
scanf("%lld", &x);
digits += extend(last, x);
}
printf("%lld\n", digits);
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 | #include <cstdio> #include <cstdint> #include <cmath> using namespace std; int b10l(int64_t x) { int i = 1; int64_t t = 10; while (1) { if (x < t) { return i; } t *= 10; ++i; } } const int MAX_LENGTH = 17; const int MIN_LENGTH = 10; struct extnum_t { int64_t prefix; int zeros; }; void extnum_init(extnum_t& e, int64_t prefix, int zeros = 0) { int plen = b10l(prefix); if (plen + zeros <= MAX_LENGTH) { e.prefix = prefix * (int64_t)pow(10LL, zeros); e.zeros = 0; } else if (plen >= MIN_LENGTH) { e.prefix = prefix / (int64_t)pow(10LL, plen - MIN_LENGTH); e.zeros = zeros + plen - MIN_LENGTH; } else { e.prefix = prefix * (int64_t)pow(10LL, MIN_LENGTH - plen); e.zeros = zeros + MIN_LENGTH - plen; } } bool is_prefix(int64_t what, int64_t of, int l1 = 0, int l2 = 0) { if (!l1) { l1 = b10l(what); } if (!l2) { l2 = b10l(of); } if (l1 > l2) { return false; } of /= (int64_t)pow(10, l2 - l1); return what == of; } int extend(extnum_t& n, int64_t prefix) { int l1 = b10l(n.prefix); int l2 = b10l(prefix); if (is_prefix(prefix, n.prefix, l2, l1)) { int ret = n.zeros + l1 - l2; if (n.zeros) { return ret; } if (l1 == l2 || n.prefix % (int64_t)pow(10, l1 - l2) + 1 == (int64_t)pow(10, l1 - l2)) { extnum_init(n, prefix, l1 - l2 + 1); ++ret; } else { extnum_init(n, n.prefix + 1); } return ret; } if (l2 > l1) { n.zeros = 0; n.prefix = prefix; return 0; } int ret = l1 - l2; prefix *= (int64_t)pow(10LL, ret); if (prefix > n.prefix) { n.prefix = prefix; ret += n.zeros; } else { ret += n.zeros + 1; extnum_init(n, prefix, n.zeros + 1); } return ret; } int main () { int n; scanf("%d", &n); extnum_t last; int64_t x; scanf("%lld", &x); extnum_init(last, x); int64_t digits = 0; for (int i = 1; i < n; ++i) { int64_t x; scanf("%lld", &x); digits += extend(last, x); } printf("%lld\n", digits); return 0; } |
English