#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; } |