QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#351826 | #6300. Best Carry Player 2 | mendicillin2 | RE | 0ms | 0kb | C++20 | 3.1kb | 2024-03-12 15:45:27 | 2024-03-12 15:45:28 |
answer
#include <bits/stdc++.h>
using namespace std;
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;
template <class F> struct ycr {
F f;
template <class T> explicit ycr(T&& f_) : f(forward<T>(f_)) {}
template <class... A> decltype(auto) operator()(A&&... as) {
return f(ref(*this), forward<A>(as)...);
}
};
template <class F> decltype(auto) yc(F&& f) {
return ycr<decay_t<F>>(forward<F>(f));
}
template <class T> void setmin(T& a, const T& b) {
if (b < a) a = b;
}
using ll = int64_t;
using i128 = __uint128_t;
string i128_to_string(i128 n) {
assert(n > 0);
string res;
while (n > 0) {
res += char(int(n % 10) + '0');
n /= 10;
}
reverse(res.begin(), res.end());
return res;
}
const int L = 37;
V<i128> p10(L);
string solve(ll X, int K) {
V<int> Xdigits(L);
{
auto t = X;
for (int l = 0; l < L; l++) {
Xdigits[l] = int(t % 10);
t /= 10;
}
assert(t == 0);
}
if (false) {
int f = 0;
while (Xdigits[f] == 9) {
f++;
}
return string("1") + string(f, '0');
}
//assert(K >= 1);
// dp(# of carries, carry)
const i128 INF = i128(-1);
VV<i128> dp(K+1, V<i128>(2, INF));
dp[0][0] = 0;
for (int l = 0; l < L; l++) {
// TODO: Check feasibility of (l+1)-digit y
if (l > 0) {
i128 cnd = dp[K][0];
if (cnd < INF) {
return i128_to_string(cnd);
}
}
int vx = Xdigits[l];
VV<i128> ndp(K+1, V<i128>(2, INF));
for (int num_carries = 0; num_carries <= K; num_carries++) {
for (int carry : {0, 1}) {
if (dp[num_carries][carry] == INF) continue;
for (int vy = 0; vy < 10; vy++) {
int new_carry = (vx + vy + carry) / 10;
int new_num_carries = num_carries + new_carry;
if (new_num_carries <= K) {
setmin(ndp[new_num_carries][new_carry], dp[num_carries][carry] + vy * p10[l]);
}
}
}
}
swap(dp, ndp);
}
// ok
assert(false);
}
string solve_naive(const ll X_orig, ll K) {
auto compute_num_carries = [&](ll Y) -> int {
assert(X_orig > 0 && Y > 0);
ll X = X_orig;
int carry = 0;
int res = 0;
while (X > 0 || Y > 0) {
if ((X == 0 || Y == 0) && carry == 0) break;
carry = int((X % 10 + Y % 10 + carry) / 10);
res += carry;
X /= 10, Y /= 10;
}
return res;
};
for (ll y = 1; ; y++) {
if (compute_num_carries(y) == K) {
return to_string(y);
}
}
}
constexpr bool TESTING = false;
mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());
template <class T>
T rand_int(T lo, T hi) {
return uniform_int_distribution<T>(lo, hi)(mt);
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr);
cout << fixed << setprecision(20);
p10[0] = 1;
for (int l = 1; l < L; l++) {
p10[l] = p10[l-1] * i128(10);
}
int T;
cin >> T;
while (T--) {
ll X;
int K;
if constexpr (!TESTING) {
cin >> X >> K;
} else {
X = rand_int(1, 999999);
K = rand_int(0, 7);
}
auto res = solve(X, K);
cout << res << '\n';
if constexpr (TESTING) {
assert(res == solve_naive(X, K));
cout << flush;
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
4 12345678 0 12345678 5 12345678 18 990099 5