QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#557023 | #2835. Number Theory | ucup-team1198 | WA | 952ms | 29920kb | C++20 | 5.4kb | 2024-09-11 00:11:35 | 2024-09-11 00:11:35 |
Judging History
answer
#include <map>
#include <set>
#include <array>
#include <cmath>
#include <deque>
#include <bitset>
#include <random>
#include <string>
#include <vector>
#include <cassert>
#include <complex>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
using namespace std;
const int INF = 1e9;
const int MAXN = 5e3 + 100;
const int MAXD = 30;
int pre_dp[2][2 * 6 * MAXN][2 * MAXD + 1];
int dp[2][2 * 6 * MAXN][3];
int lst(int x) {
int res = x % 10;
if (res < 0) res += 10;
return res;
}
int rest(int x) {
return (x - lst(x)) / 10;
}
int rest9(int x) {
int r = x % 9;
if (r < 0) r += 9;
return (x - r) / 9;
}
int solve(string ns) {
reverse(ns.begin(), ns.end());
ns.push_back('0');
ns.push_back('0');
ns.push_back('0');
vector<int> n;
for (char ch : ns) {
n.push_back(ch - '0');
}
int l = n.size();
int maxc = 5 * l + 30;
int maxd = (maxc + 89) / 90;
for (int i = 0; i <= 1; ++i) {
for (int j = -maxc; j <= maxc; ++j) {
fill(dp[i][j + maxc], dp[i][j + maxc] + 2 * MAXD + 1, INF);
}
}
for (int c = -maxc; c <= maxc; ++c) {
fill(pre_dp[0][c + maxc], pre_dp[0][c + maxc] + 2 * MAXD + 1, INF);
}
for (int c = -maxc; c <= maxc; ++c) {
if (lst(c) != n[0])
continue;
int carry = rest(c);
int val = 0;
int rem = lst(n[1] - carry);
int start = rest(c - rem) * 10 + rem;
for (int c1 = start; c1 <= c + 6; c1 += 10) {
int val1 = val + abs(c - c1);
int carry1 = rest(carry + c1);
int delta1 = carry1 - rest9(c1);
//cerr << "to " << 2 << ' ' << c1 << ' ' << delta1 << ' ' << val1 << '\n';
pre_dp[0][maxc + c1][MAXD + delta1] = min(pre_dp[0][maxc + c1][MAXD + delta1], val1);
}
}
maxd = (maxd + 10) / 10;
for (int i = 2; i < 4; ++i) {
for (int c = -maxc; c <= maxc; ++c) {
fill(pre_dp[(i + 1) % 2][c + maxc] + MAXD - maxd - 1, pre_dp[(i + 1) % 2][c + maxc] + MAXD + maxd + 1, INF);
}
int cur_maxc = (l - i) * 5 + 10;
for (int c = -cur_maxc; c <= cur_maxc; ++c) {
for (int delta = -maxd; delta <= maxd; ++delta) {
int val = pre_dp[i % 2][c + maxc][delta + MAXD];
if (val == INF) continue;
//cerr << i << ' ' << c << ' ' << delta << ' ' << val << '\n';
int carry = rest9(c) + delta;
int rem = lst(n[i] - carry);
int start = rest(c - rem) * 10 + rem;
for (int c1 = start; c1 <= c + 6; c1 += 10) {
int val1 = val + i * abs(c - c1);
int carry1 = rest(carry + c1);
int delta1 = carry1 - rest9(c1);
//cerr << " to " << i + 1 << ' ' << c1 << ' ' << delta1 << ' ' << val1 << '\n';
pre_dp[(i + 1) % 2][maxc + c1][MAXD + delta1] = min(pre_dp[(i + 1) % 2][maxc + c1][MAXD + delta1], val1);
}
}
}
maxd = (maxd + 10) / 10;
}
for (int c = -maxc; c <= maxc; ++c) {
for (int d = -1; d <= 1; ++d)
dp[4 & 1][c + maxc][1 + d] = pre_dp[4 & 1][c + maxc][MAXD + d];
}
for (int i = 4; i < l; ++i) {
int cur_maxc = (l - i) * 5 + 10;
for (int c = -cur_maxc; c <= cur_maxc; ++c) {
fill(dp[(i + 1) % 2][c + maxc], dp[(i + 1) % 2][c + maxc] + 3, INF);
}
for (int c = -cur_maxc; c <= cur_maxc; ++c) {
for (int delta = -maxd; delta <= maxd; ++delta) {
int val = dp[i % 2][c + maxc][delta + 1];
if (val == INF) continue;
//cerr << i << ' ' << c << ' ' << delta << ' ' << val << '\n';
int carry = rest9(c) + delta;
int rem = lst(n[i] - carry);
int start = rest(c - rem) * 10 + rem;
for (int c1 = start; c1 <= c + 6; c1 += 10) {
int val1 = val + i * abs(c - c1);
int carry1 = rest(carry + c1);
int delta1 = carry1 - rest9(c1);
//cerr << " to " << i + 1 << ' ' << c1 << ' ' << delta1 << ' ' << val1 << '\n';
dp[(i + 1) % 2][maxc + c1][1 + delta1] = min(dp[(i + 1) % 2][maxc + c1][1 + delta1], val1);
}
}
}
}
int ans = INF;
for (int i = -maxc; i <= maxc; ++i) {
for (int delta = -1; delta <= 1; ++delta) {
int carry = rest9(i) + delta;
if (carry == 0) {
ans = min(ans, dp[l % 2][i + maxc][1 + delta]);
}
}
}
return ans;
}
//#define STRESS
#define RANDOM
#ifdef STRESS
const int LEN = 7;
const int K = 500000;
int precalc[K];
void gen(int i, int cur, int cost, int num) {
if (i == LEN) {
if (0 < cur && cur < K) {
precalc[cur] = min(precalc[cur], cost);
}
return;
}
for (int j = -7; j <= 7; ++j) {
gen(i + 1, cur + j * num, cost + abs(j) * i, num * 10 + 1);
}
}
int dumb(string n) {
int x = stoi(n);
return precalc[x];
}
#endif
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
#if defined(STRESS)
fill(precalc, precalc + K, INF);
gen(1, 0, 0, 1);
for (int n = 1; n < K; ++n) {
string ns = to_string(n);
int ans1 = solve(ns);
int ans2 = dumb(ns);
if (ans1 != ans2) {
cerr << "BUG!!\n";
cerr << ns << '\n';
cerr << "wrong: " << ans1 << " right: " << ans2 << "\n\n\n";
break;
}
}
#elif defined(RANDOM)
const int L = 5000;
string n;
for (int i = 0; i < L; ++i)
n += char('0' + rand() % 10);
cout << solve(n) << '\n';
#else
string n;
while (cin >> n) {
cout << solve(n) << '\n';
}
#endif
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 952ms
memory: 29920kb
input:
12 100 998244353
output:
30950849
result:
wrong answer 1st lines differ - expected: '3', found: '30950849'