QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#351826#6300. Best Carry Player 2mendicillin2RE 0ms0kbC++203.1kb2024-03-12 15:45:272024-03-12 15:45:28

Judging History

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

  • [2024-03-12 15:45:28]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-03-12 15:45:27]
  • 提交

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

output:


result: