QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#637110#8769. Champernowne Substringnhuang685WA 612ms3640kbC++2310.3kb2024-10-13 09:42:572024-10-13 09:42:59

Judging History

你现在查看的是最新测评结果

  • [2024-10-13 09:42:59]
  • 评测
  • 测评结果:WA
  • 用时:612ms
  • 内存:3640kb
  • [2024-10-13 09:42:57]
  • 提交

answer

/**
 * @author n685
 * @brief
 * @date 2024-10-12 11:22:13
 *
 *
 */
#include "bits/stdc++.h"

#ifdef LOCAL
#include "dd/debug.h"
#else
#define dbg(...) 42
#define dbg_proj(...) 420
#define dbg_rproj(...) 420420
void nline() {}
void bar() {}
void start_clock() {}
void end_clock() {}
#endif

using i128 = __int128_t;
template <class T> constexpr T INF = T{};
template <> constexpr int INF<int> = 0x3f3f3f3f;                 // 1061109567
template <> constexpr int64_t INF<int64_t> = 0x3f3f3f3f3f3f3f3f; // 4557430888798830399
template <>
constexpr i128 INF<i128>
    = i128{INF<int64_t>} << 64 | INF<int64_t>; // 84069761239290679208598432424319205183

constexpr int MOD = 998'244'353;
constexpr int MXLG = 25;
constexpr std::array<i128, MXLG + 1> p10 = []() {
    std::array<i128, MXLG + 1> ans{};
    ans[0] = 1;
    for (int i = 1; i <= MXLG; ++i) {
        ans[i] = ans[i - 1] * 10;
    }
    return ans;
}();
int log10(i128 val) {
    for (int i = 0; i <= MXLG; ++i) {
        if (val < p10[i]) {
            return i - 1;
        }
    }
    return MXLG;
}

i128 pos(i128 val) {
    int lg = log10(val);
    i128 ans = 0;
    for (int i = lg; i >= 0; --i) {
        ans += (i + 1) * (val - p10[i] + 1);
        val = p10[i] - 1;
    }
    return ans;
}
std::string to_string(i128 val) {
    if (val <= std::numeric_limits<uint64_t>::max()) {
        return std::to_string(static_cast<uint64_t>(val));
    }
    std::string ans;
    while (val > 0) {
        ans += static_cast<char>('0' + val % 10);
        val /= 10;
    }
    std::reverse(ans.begin(), ans.end());
    return ans;
}
i128 stoi128(const std::string& s) {
    i128 ans = 0;
    for (char c : s) {
        assert(c != '?');
        ans = 10 * ans + (c - '0');
    }
    return ans;
}

bool match(const std::string& s, const std::string& ls) {
    int n = static_cast<int>(s.size());
    for (int i = 0; i < n; ++i) {
        if (s[i] != '?' && ls[i] != '?' && s[i] != ls[i]) {
            return false;
        }
    }
    return true;
}

constexpr int MX = 100000;
void solve() {
    std::string s;
    std::cin >> s;
    int n = static_cast<int>(s.size());
    i128 ans = INF<i128>;

    // starts from 1..10^5
    for (i128 i = 1; i <= MX; ++i) {
        int lg = log10(i);
        for (int st = -lg; st <= 0; ++st) {
            std::string ls;
            for (i128 val = i; static_cast<int>(ls.size()) + st < n; ++val) {
                ls += to_string(val);
            }
            if (match(s, ls.substr(-st))) {
                ans = std::min(ans, pos(i - 1) + 1 - st);
            }
        }
    }

    // includes power of 10
    for (int lg = 5; lg <= MXLG; ++lg) {
        for (int p = -lg; p < n; ++p) {
            int st = p;
            i128 fi = p10[lg];
            while (st > 0) {
                st -= lg;
                --fi;
            }
            std::string ls;
            for (i128 val = fi; static_cast<int>(ls.size()) + st < n; ++val) {
                ls += to_string(val);
            }
            if (match(s, ls.substr(-st))) {
                ans = std::min(ans, pos(fi - 1) + 1 - st);
            }
        }
    }

    // one number
    {
        std::string ls = s;
        for (int i = 1; i < static_cast<int>(ls.size()); ++i) {
            if (ls[i] == '?') {
                ls[i] = '0';
            }
        }
        int off = 0;
        if (ls[0] == '0') {
            ++off;
            ls.insert(ls.begin(), '1');
        } else if (ls[0] == '?') {
            ls[0] = '1';
        }
        ans = std::min(ans, pos(stoi128(ls) - 1) + off + 1);
    }

    // no carry
    for (int lg = 5; lg <= MXLG; ++lg) {
        int wi = lg + 1;
        int tp = (wi - n % wi) % wi;
        int sz = n + tp;
        for (int pl = 0; pl <= tp; ++pl) {
            int pr = tp - pl;
            std::string ss = std::string(pl, '?') + s + std::string(pr, '?');
            std::string ls(wi, '?');
            bool g = true;
            for (int i = 0; i < sz; i += wi) {
                for (int j = 0; j < wi; ++j) {
                    if (ss[i + j] == '?') {
                        continue;
                    }
                    if (j == wi - 1) {
                        int dv = ss[i + j] - '0';
                        if (dv < i / wi || ls[j] - '0' != dv - i / wi) {
                            g = false;
                            break;
                        }
                        ls[j] = static_cast<char>(dv - i / wi + '0');
                    } else {
                        int dv = ss[i + j] - '0';
                        if ((j == 0 && dv == 0) || ls[j] != ss[i + j]) {
                            g = false;
                            break;
                        }
                        ls[j] = ss[i + j];
                    }
                }
            }
            if (g && ls[0] != '0') {
                if (ls[0] == '?') {
                    ls[0] = '1';
                }
                for (int i = 1; i < wi; ++i) {
                    if (ls[i] == '?') {
                        ls[i] = '0';
                    }
                }
                ans = std::min(ans, pos(stoi128(ls) - 1) + pl + 1);
            }
        }
    }

    // carry
    for (int lg = 5; lg <= MXLG; ++lg) {
        int wi = lg + 1;
        int tp = (wi - n % wi) % wi;
        int sz = n + tp;
        for (int pl = 0; pl <= tp; ++pl) {
            int pr = tp - pl;
            std::string ss = std::string(pl, '?') + s + std::string(pr, '?');
            for (int cpos = wi; cpos < sz; cpos += wi) {
                for (int cw = 1; cw < wi; ++cw) {
                    std::string ls(wi, '?');
                    ls[wi - 1] = static_cast<char>(10 - cpos / wi + '0');
                    for (int i = wi - cw; i < wi - 1; ++i) {
                        ls[i] = '9';
                    }
                    bool g = true;
                    for (int i = 0; i < cpos; i += wi) {
                        for (int j = 0; j < wi; ++j) {
                            if (ss[i + j] == '?') {
                                continue;
                            }
                            if (j == wi - 1) {
                                int dv = ss[i + j] - '0';
                                if (dv < i / wi || (ls[j] != '?' && ls[j] - '0' != dv - i / wi)) {
                                    g = false;
                                    break;
                                }
                                ls[j] = static_cast<char>(dv - i / wi + '0');
                            } else {
                                int dv = ss[i + j] - '0';
                                if (i >= wi - cw && dv != 9) {
                                    g = false;
                                    break;
                                }
                                if (i == wi - cw - 1 && dv == 9) {
                                    g = false;
                                    break;
                                }
                                if ((j == 0 && dv == 0) || (ls[j] != '?' && ls[j] != ss[i + j])) {
                                    g = false;
                                    break;
                                }
                                ls[j] = ss[i + j];
                            }
                        }
                    }
                    if (!g) {
                        continue;
                    }
                    for (int i = cpos; i < sz; i += wi) {
                        for (int j = 0; j < wi; ++j) {
                            if (ss[i + j] == '?') {
                                continue;
                            }
                            if (j == wi - 1) {
                                int dv = ss[i + j] - '0';
                                int od = dv - i / wi + 10;
                                if (ls[j] - '0' != od) {
                                    g = false;
                                    break;
                                }
                                ls[j] = static_cast<char>(od + '0');
                            } else {
                                int dv = ss[i + j] - '0';
                                if (j >= wi - cw) {
                                    if (dv != 0) {
                                        g = false;
                                        break;
                                    }
                                    dv = 9;
                                } else if (j == wi - cw - 1) {
                                    if (dv == 0) {
                                        g = false;
                                        break;
                                    }
                                    --dv;
                                }
                                if ((j == 0 && dv == 0) || (ls[j] != '?' && ls[j] != dv + '0')) {
                                    g = false;
                                    break;
                                }
                                ls[j] = static_cast<char>(dv + '0');
                            }
                        }
                    }
                    if (g && ls[0] != '0') {
                        if (ls[0] == '?') {
                            ls[0] = '1';
                        }
                        for (int i = 1; i < wi - cw; ++i) {
                            if (ls[i] == '?') {
                                ls[i] = '0';
                            }
                        }
                        ans = std::min(ans, pos(stoi128(ls) - 1) + pl + 1);
                    }
                }
            }
        }
    }

    dbg(to_string(ans));
#ifdef LOCAL
    i128 l = 1, r = static_cast<i128>(2e25);
    while (l < r) {
        i128 mid = l + (r - l) / 2;
        if (pos(mid) + 1 >= ans) {
            r = mid;
        } else {
            l = mid + 1;
        }
    }
    dbg(to_string(l));
#endif
    std::cout << static_cast<int>(ans % MOD) << '\n';
}

int main() {
#ifndef LOCAL
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
#endif

    int t;
    std::cin >> t;
    for (int i = 0; i < t; ++i) {
        dbg(i + 1);
        solve();
        bar();
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 281ms
memory: 3640kb

input:

9
0
???1
121
1?1?1
??5?54?50?5?505?65?5
000000000000
?2222222
?3????????9??8???????1??0
9?9??0????????????2

output:

11
7
14
10
314159
796889014
7777
8058869
38886

result:

ok 9 lines

Test #2:

score: -100
Wrong Answer
time: 612ms
memory: 3572kb

input:

10
0000000000000000000000000
0000000?002100000000000?0
6999?999?999999989?999999
0???0?1000?0??000?????0?1
9??9?999998?9?999999100?0
96?9997999?8999991????010
99?99??999999999??????99?
?0?0000?00000000?0210?0?0
99?999?999?99?9??999?9?9?
9?????9?99?99??9??99??9??

output:

545305036
237403177
73613435
583252822
902934046
488873
68888876
329890171
68888869
5882870

result:

wrong answer 2nd lines differ - expected: '574985081', found: '237403177'