Problem A: Numerical Triplet Verification
Determine whether a sequence of three integers strictly consists of two fives and one seven. Ordering the inputs simplifies validation. Applying an ascending sort arranges the values sequentially, allowing a direct equality check against the target pattern. This approach eliminates conditional branching and ensures consistent evaluation regardless of initial permutation.
#include <algorithm>
#include <array>
#include <iostream>
int main() {
std::array<int, 3> vals;
std::cin >> vals[0] >> vals[1] >> vals[2];
std::sort(vals.begin(), vals.end());
if (vals[0] == 5 && vals[1] == 5 && vals[2] == 7) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
return 0;
}
Problem B: Optimal String Concatenation
Arrange a collection of strings of uniform length to minimize the lexicographical value of their concatenation. When lengths match, standard alphabetical sorting suffices. For variable-length sequences, the ordering criterion depends on comparative concatenation. Specifically, sequence $P$ should precede $Q$ if the string $P + Q$ ranks lower than $Q + P$. This relation maintains transitivity, permitting standard sort routines to produce the globally minimal arrangement. The computational overhead scales linearly with total character count multiplied by the logarithmic factor of the string count.
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
int main() {
int n, l;
std::cin >> n >> l;
std::vector<std::string> pieces(n);
for (auto& s : pieces) std::cin >> s;
std::sort(pieces.begin(), pieces.end(), [](const std::string& a, const std::string& b) {
return a + b < b + a;
});
for (const auto& s : pieces) std::cout << s;
std::cout << "\n";
return 0;
}
Problem C: Restricted Digit Enumeration
Locate the smallest integer not less than a threshold $n$ that excludes a specified subset of decimal digits. Direct iteration proves efficient for moderate thresholds due to the sparse nature of valid numbers. For extended ranges, a constructive digit-generation strategy outperforms brute force. The resultant candidate will possess either the same number of digits as $n$ or exactly one additional digit. Algorithmically, validate the leading position against allowable candidates, then fill subseuqent positions with the lowest permitted numeral. Maintaining a boolean exclusion map accelerates per-digit checks, reducing overall complexity to linear time relative to the digit count.
#include <iostream>
#include <string>
#include <vector>
int main() {
int k;
std::cin >> k;
std::vector<bool> blocked(10, false);
for (int i = 0, d; i < k; ++i) {
std::cin >> d;
blocked[d] = true;
}
int n;
std::cin >> n;
for (long long cur = n; ; ++cur) {
std::string temp = std::to_string(cur);
bool valid = true;
for (char c : temp) {
if (blocked[c - '0']) { valid = false; break; }
}
if (valid) {
std::cout << cur << "\n";
break;
}
}
return 0;
}
Problem D: Boundary Intersection Counting
Compute valid traversal routes across a two-dimensional lattice moving exclusively rightward or downward, while circumventing a restricted rectangular sector. Instead of direct enumeration, apply complementary counting. Any invalid route must intersect the forbidden zone along a specific transitional boundary line. By parameterizing each crossing coordinate on this boundary, the complete path splits into two mathematically independent segments. The quantity of routes reaching the boundary utilizes standard binomial coefficient calculations, mirroring the routes extending from the boundary to the destination. Multiplying these segment counts per coordinate and aggregating the results yields the total valid configurations. Factorial precomputation modulo $10^9+7$ facilitates rapid combination evaluations.
#include <iostream>
#include <vector>
using ll = long long;
const int MOD = 1e9 + 7;
class Combinatorics {
std::vector<ll> fact, invFact;
public:
Combinatorics(int n) : fact(n + 1), invFact(n + 1) {
fact[0] = 1;
for (int i = 1; i <= n; i++) fact[i] = (fact[i - 1] * i) % MOD;
invFact[n] = power(fact[n], MOD - 2);
for (int i = n - 1; i >= 0; i--) invFact[i] = (invFact[i + 1] * (i + 1)) % MOD;
}
ll nCr(int n, int r) {
if (r < 0 || r > n) return 0;
return fact[n] * invFact[r] % MOD * invFact[n - r] % MOD;
}
private:
ll power(ll base, ll exp) {
ll res = 1;
base %= MOD;
while (exp > 0) {
if (exp % 2 == 1) res = (res * base) % MOD;
base = (base * base) % MOD;
exp /= 2;
}
return res;
}
};
int main() {
int H, W, A, B;
std::cin >> H >> W >> A >> B;
Combinatorics combos(H + W);
ll totalPaths = 0;
int barrierRow = H - A;
for (int col = B + 1; col <= W; col++) {
ll waysToBarrier = combos.nCr(barrierRow + col - 2, barrierRow - 1);
ll waysFromBarrier = combos.nCr((H - barrierRow) + (W - col), H - barrierRow);
ll segmentProduct = (waysToBarrier * waysFromBarrier) % MOD;
totalPaths = (totalPaths + segmentProduct) % MOD;
}
std::cout << totalPaths << "\n";
return 0;
}