Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
You do not need to construct every valid . The best answer must come from either the greatest valid number or the smallest valid number .
Compare numbers as decimal strings. For a candidate with the same length as , if it is not equal to , then there is a first position where it differs; before it must match exactly.
For the largest valid number below , at the first differing position choose the largest allowed digit , then fill the rest with the largest allowed digit. The upper side is symmetric: choose the smallest allowed digit , then fill the rest with the smallest allowed digit.
Do not forget the boring-but-deadly trap: no leading zero unless the whole number is . Also, numbers with fewer digits and more digits must be considered separately.
Enumerate the first differing position for the same length. Keep the prefix valid, generate one floor candidate and one ceiling candidate per , add the best shorter/longer length candidates, then output .
We need
If we know the closest valid number from below and from above,
then the answer is simply
ignoring a side if it does not exist. So the whole problem is: build and greedily.
Let be the decimal representation of , with length .
Consider a valid number with the same length as and . Let be the first position where differs from . Then
For this fixed first differing position , the best possible smaller number is obvious:
and every later digit should be as large as possible:
That gives the largest valid number below with first difference at .
The upper side is the exact mirror. For with first difference at :
Of course, this only works while the prefix itself consists of allowed digits. If the prefix is already invalid, it cannot be equal to a valid number's prefix. No magic, no DP monster, just first-difference bookkeeping.
Also: no leading zero for multi-digit numbers. This is the tiny annoying detail that eats wrong submissions for breakfast.
Any valid number with fewer than digits is automatically smaller than . We can just generate the maximum valid number for every length and take the maximum.
Any valid number with more than digits is automatically larger than . The smallest such useful length is , so we generate the minimum valid number of length if it fits the constraints.
For a fixed length:
Since , . All useful candidates have at most digits. If , we do not need to build a -digit upper candidate: if a nonzero digit exists, some same-length valid number is already at least ; otherwise the only possible valid number is .
For each test case:
The algorithm finds the greatest valid number of the same length as that is at most .
Proof. If itself is valid, the algorithm includes it. Otherwise, take any valid same-length number . Let be the first position where differs from . Then all earlier digits must equal and must be allowed, so the algorithm considers this . Since , we must have . For this same , choosing the largest allowed digit below and filling the rest with produces a valid number at least as large as . Therefore, taking the maximum over all considered gives the best possible same-length floor.
The algorithm finds the smallest valid number of the same length as that is at least .
Proof. Symmetric to Lemma 1. For any valid same-length , at the first differing position we have . The algorithm chooses the smallest allowed digit above and fills the suffix with , producing a valid number no larger than for that . Taking the minimum over all gives the best same-length ceiling.
The algorithm correctly handles valid numbers of different lengths.
Proof. Every valid number with fewer digits than is smaller than , so the best such number is the maximum valid number among those lengths; the algorithm checks them. Every valid number with more digits than is larger than , and among longer lengths the shortest possible length gives the smallest value, so checking length is enough when it can matter.
The algorithm outputs the minimum possible value of .
Proof. By Lemmas 1 and 3, the computed is the greatest valid number not exceeding . By Lemmas 2 and 3, the computed is the smallest valid number not less than . Any valid is no better than , and any valid is no better than . Therefore the optimal answer is exactly
Let be the number of digits of , so , and let .
For each position we scan the digit set, and building candidate strings is tiny:
per test case, which is effectively constant. Memory usage is
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
ll valueOf(const string& s) {
ll x = 0;
for (char c : s) x = x * 10 + (c - '0');
return x;
}
int main() {
setIO();
int T;
cin >> T;
const ll INF = 4'000'000'000'000'000'000LL;
while (T--) {
ll a;
int n;
cin >> a >> n;
vector<int> dig(n);
bool have[10] = {};
for (int i = 0; i < n; i++) {
cin >> dig[i];
have[dig[i]] = true;
}
int mn = dig.front();
int mx = dig.back();
int mnNZ = -1;
for (int x : dig) {
if (x > 0) {
mnNZ = x;
break;
}
}
auto minLen = [&](int len) -> ll {
if (len == 1) return mn;
if (mnNZ == -1) return INF;
ll x = mnNZ;
for (int i = 1; i < len; i++) x = x * 10 + mn;
return x;
};
auto maxLen = [&](int len) -> ll {
if (len == 1) return mx;
if (mx == 0) return -1;
ll x = 0;
for (int i = 0; i < len; i++) x = x * 10 + mx;
return x;
};
string s = to_string(a);
int L = (int)s.size();
ll lo = -1;
ll hi = INF;
bool prefixOK = true;
for (int i = 0; i < L; i++) {
int cur = s[i] - '0';
if (prefixOK) {
int down = -1;
for (int x : dig) {
if (x < cur && !(i == 0 && L > 1 && x == 0)) {
down = x;
}
}
if (down != -1) {
string t = s.substr(0, i);
t.push_back(char('0' + down));
while ((int)t.size() < L) t.push_back(char('0' + mx));
lo = max(lo, valueOf(t));
}
int up = -1;
for (int x : dig) {
if (x > cur && !(i == 0 && L > 1 && x == 0)) {
up = x;
break;
}
}
if (up != -1) {
string t = s.substr(0, i);
t.push_back(char('0' + up));
while ((int)t.size() < L) t.push_back(char('0' + mn));
hi = min(hi, valueOf(t));
}
}
if (!have[cur]) prefixOK = false;
}
if (prefixOK) {
lo = max(lo, a);
hi = min(hi, a);
}
for (int len = 1; len < L; len++) {
ll v = maxLen(len);
if (v != -1) lo = max(lo, v);
}
if (L < 18) {
ll v = minLen(L + 1);
if (v != INF) hi = min(hi, v);
}
ll ans = INF;
if (lo != -1) ans = min(ans, a - lo);
if (hi != INF) ans = min(ans, hi - a);
cout << ans << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
ll valueOf(const string& s) {
ll x = 0;
for (char c : s) x = x * 10 + (c - '0');
return x;
}
int main() {
setIO();
int T;
cin >> T;
const ll INF = 4'000'000'000'000'000'000LL;
while (T--) {
ll a;
int n;
cin >> a >> n;
vector<int> dig(n);
bool have[10] = {};
for (int i = 0; i < n; i++) {
cin >> dig[i];
have[dig[i]] = true;
}
int mn = dig.front();
int mx = dig.back();
int mnNZ = -1;
for (int x : dig) {
if (x > 0) {
mnNZ = x;
break;
}
}
auto minLen = [&](int len) -> ll {
if (len == 1) return mn;
if (mnNZ == -1) return INF;
ll x = mnNZ;
for (int i = 1; i < len; i++) x = x * 10 + mn;
return x;
};
auto maxLen = [&](int len) -> ll {
if (len == 1) return mx;
if (mx == 0) return -1;
ll x = 0;
for (int i = 0; i < len; i++) x = x * 10 + mx;
return x;
};
string s = to_string(a);
int L = (int)s.size();
ll lo = -1;
ll hi = INF;
bool prefixOK = true;
for (int i = 0; i < L; i++) {
int cur = s[i] - '0';
if (prefixOK) {
int down = -1;
for (int x : dig) {
if (x < cur && !(i == 0 && L > 1 && x == 0)) {
down = x;
}
}
if (down != -1) {
string t = s.substr(0, i);
t.push_back(char('0' + down));
while ((int)t.size() < L) t.push_back(char('0' + mx));
lo = max(lo, valueOf(t));
}
int up = -1;
for (int x : dig) {
if (x > cur && !(i == 0 && L > 1 && x == 0)) {
up = x;
break;
}
}
if (up != -1) {
string t = s.substr(0, i);
t.push_back(char('0' + up));
while ((int)t.size() < L) t.push_back(char('0' + mn));
hi = min(hi, valueOf(t));
}
}
if (!have[cur]) prefixOK = false;
}
if (prefixOK) {
lo = max(lo, a);
hi = min(hi, a);
}
for (int len = 1; len < L; len++) {
ll v = maxLen(len);
if (v != -1) lo = max(lo, v);
}
if (L < 18) {
ll v = minLen(L + 1);
if (v != INF) hi = min(hi, v);
}
ll ans = INF;
if (lo != -1) ans = min(ans, a - lo);
if (hi != INF) ans = min(ans, hi - a);
cout << ans << '\n';
}
return 0;
}