Hey everyone
I recently participated in Meta Hacker Cup 2025 Round 1 and I’m thrilled to share that I secured Rank 333 / 13,676 with a perfect score of 105/105, successfully solving every problem from A1 → D!
I've qualified for Round 2 of the Meta Hacker Cup 2025! Round 1 was a fantastic set of problems, and I managed to solve all of them for a full score.
This post includes my hints, solution approaches, and final codes for all problems — written to help learners strengthen their DSA and problem-solving intuition.
A1: Snakes Scales (Chapter 1) :
Snake must walk from platform 1 to N. To get from platform $$$i$$$ to $$$i+1$$$, he needs a ladder of height $$$|A_i - A_{i+1}|$$$. Since he brings only one ladder, it must be tall enough for the hardest (i.e., highest) adjacent jump in the entire path.
The shortest ladder must be as tall as the largest height difference between any two adjacent platforms. Iterate from $$$i=1$$$ to $$$N-1$$$ and find the maximum value of $$$|A_i - A_{i+1}|$$$. This maximum value is the answer. If $$$N=1$$$, no moves are needed, so the answer is 0.
#include <bits/stdc++.h>
using namespace std;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM =
chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
#define prDouble(x) cout<<fixed<<setprecision(10)<<x
#define fastio() ios::sync_with_stdio(false); cin.tie(nullptr)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
using ll = long long;
using ld = long double;
using pll = pair<ll,ll>;
using tll = tuple<ll,ll,ll>;
using vll = vector<ll>;
using vpll = vector<pll>;
vector<ll> dx = {1, -1, 0, 0}, dy = {0, 0, 1, -1}; // for grid
vector<ll> ddx = {1,1,0,-1,-1,-1,0,1}, ddy = {0,1,1,1,0,-1,-1,-1}; // 8 directions
template<typename T> void read(vector<T> &v) { for (auto &x : v) cin >> x; }
template<typename T> void printv(const vector<T>& v) { for (auto &x : v) cout << x << ' '; }
template<typename T> void print2d(const vector<vector<T>>& v) { for (auto &row : v) { for (auto &x : row) cout << x << ' '; cout << '\n'; } }
ll t=1,n,m,p,q,r,k,a,b,c,x,y,z;
const ll INF = 1e18, MOD = 1e9+7;
void solve() {
cin>>n;
vector<ll> a(n);
read(a);
ll ans = 0;
for(int i=0;i<n-1;i++){
ans = max(ans,abs(a[i]-a[i+1]));
}
cout<<ans<<"\n";
}
int main() {
fastio();
cin >> t;
for (ll i=1; i<=t; i++) {
cout << "Case #" << i << ": ";
solve();
}
return 0;
}
A2: Snakes Scales (Chapter 2) :
If a 10-foot ladder works, a 20-foot one will too. This monotonicity points to Binary Search on the Answer. The real problem is: for a given height $$$h$$$, can you visit all platforms? Think of this as a graph connectivity problem. Use BFS/DFS starting from all platforms reachable from the ground.
Binary search for the answer $$$h$$$. The check(h) function uses a BFS. Start the BFS by adding all platforms $$$i$$$ where $$$A_i \le h$$$ (ground access) to the queue. Then, explore adjacent platforms $$$j$$$ if $$$|A_i - A_j| \le h$$$. If the total visited count reaches $$$N$$$, check(h) is true.
#include <bits/stdc++.h>
using namespace std;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM =
chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
#define prDouble(x) cout<<fixed<<setprecision(10)<<x
#define fastio() ios::sync_with_stdio(false); cin.tie(nullptr)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
using ll = long long;
using ld = long double;
using pll = pair<ll,ll>;
using tll = tuple<ll,ll,ll>;
using vll = vector<ll>;
using vpll = vector<pll>;
vector<ll> dx = {1, -1, 0, 0}, dy = {0, 0, 1, -1}; // for grid
vector<ll> ddx = {1,1,0,-1,-1,-1,0,1}, ddy = {0,1,1,1,0,-1,-1,-1}; // 8 directions
template<typename T> void read(vector<T> &v) { for (auto &x : v) cin >> x; }
template<typename T> void printv(const vector<T>& v) { for (auto &x : v) cout << x << ' '; }
template<typename T> void print2d(const vector<vector<T>>& v) { for (auto &row : v) { for (auto &x : row) cout << x << ' '; cout << '\n'; } }
ll t=1,n,m,p,q,r,k,a,b,c,x,y,z;
const ll INF = 1e18, MOD = 1e9+7;
bool check(ll h, int n, const vector<ll>& a) {
if (n == 0) {
return true;
}
vector<bool> visited(n, false);
queue<int> q;
int visited_count = 0;
for (int i = 0; i < n; ++i) {
if (a[i] <= h) {
if (!visited[i]) {
q.push(i);
visited[i] = true;
visited_count++;
}
}
}
while (!q.empty()) {
int u = q.front();
q.pop();
if (u > 0 && !visited[u - 1] && abs(a[u] - a[u - 1]) <= h) {
visited[u - 1] = true;
q.push(u - 1);
visited_count++;
}
if (u < n - 1 && !visited[u + 1] && abs(a[u] - a[u + 1]) <= h) {
visited[u + 1] = true;
q.push(u + 1);
visited_count++;
}
}
return visited_count == n;
}
void solve() {
cin >> n;
vector<ll> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
ll low = 0;
ll high = 1e9 + 7;
ll ans = high;
while (low <= high) {
ll mid = low + (high - low) / 2;
if (check(mid, n, a)) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
cout << ans << "\n";
}
int main() {
fastio();
cin >> t;
for (int i = 1; i <= t; ++i) {
cout << "Case #" << i << ": ";
solve();
}
return 0;
}
B1: Final Product (Chapter 1) :
The problem asks for any valid sequence, not the fastest or best one. Think about the simplest possible "coolness" you can have after $$$N$$$ days. Given the constraints ($$$A \ge 1$$$), how can you use $$$N$$$ multipliers to guarantee you are below the limit $$$A$$$? Once that's set, how can you use the remaining $$$N$$$ multipliers to hit the target $$$B$$$ exactly?
The code uses the simplest possible valid strategy.First $$$N$$$ Days (Coolness $$$\le A$$$): To guarantee the product is $$$\le A$$$, the code sets the multiplier for each of the first $$$N$$$ days to 1. The product after $$$N$$$ days is $$$1 \times 1 \times \dots \times 1 = 1$$$. Since the constraints state $$$A \ge 1$$$, a coolness of 1 is always valid.All $$$2N$$$ Days (Coolness $$$= B$$$): The product of the first $$$N$$$ days is 1. We need the total product to be $$$B$$$. This means the product of the last $$$N$$$ days must be $$$B$$$. The code achieves this simply by setting the next $$$N-1$$$ multipliers to 1 and setting the final ($$$2N$$$-th) multiplier to $$$B$$$.The final product is $$$(\underbrace{1 \times \dots \times 1}_{N \text{ times}}) \times (\underbrace{1 \times \dots \times 1}_{N-1 \text{ times}} \times B) = 1 \times B = B$$$. This satisfies all conditions.
#include <bits/stdc++.h>
using namespace std;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM =
chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
#define prDouble(x) cout<<fixed<<setprecision(10)<<x
#define fastio() ios::sync_with_stdio(false); cin.tie(nullptr)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
using ll = long long;
using ld = long double;
using pll = pair<ll,ll>;
using tll = tuple<ll,ll,ll>;
using vll = vector<ll>;
using vpll = vector<pll>;
vector<ll> dx = {1, -1, 0, 0}, dy = {0, 0, 1, -1}; // for grid
vector<ll> ddx = {1,1,0,-1,-1,-1,0,1}, ddy = {0,1,1,1,0,-1,-1,-1}; // 8 directions
template<typename T> void read(vector<T> &v) { for (auto &x : v) cin >> x; }
template<typename T> void printv(const vector<T>& v) { for (auto &x : v) cout << x << ' '; }
template<typename T> void print2d(const vector<vector<T>>& v) { for (auto &row : v) { for (auto &x : row) cout << x << ' '; cout << '\n'; } }
ll t=1,n,m,p,q,r,k,a,b,c,x,y,z;
const ll INF = 1e18, MOD = 1e9+7;
void solve() {
cin>>n>>a>>b;
for(int i=0;i<n;i++){
cout<<1<<" ";
}
for(int i=0;i<n-1;i++){
cout<<1<<" ";
}
cout<<b<<"\n";
}
int main() {
fastio();
cin >> t;
for (ll i=1; i<=t; i++) {
cout << "Case #" << i << ": ";
solve();
}
return 0;
}
B2: Final Product (Chapter 2) :
The product of the first $$$N$$$ days, $$$d$$$, must be a divisor of $$$B$$$ and also $$$d \le A$$$. The total answer is the sum, over all valid $$$d$$$, of $$$(\text{Ways to make } d \text{ with } N \text{ multipliers}) \times (\text{Ways to make } B/d \text{ with } N \text{ multipliers})$$$. This "Ways" function is a classic "Stars and Bars" problem on the prime factorization of $$$d$$$ and $$$B/d$$$.
The code first prime-factorizes $$$B$$$. It then recursively generates all divisors $$$d$$$ of $$$B$$$, pruning any search branch that would create a divisor greater than $$$A$$$. For each valid $$$d \le A$$$, it computes the prime factors of the complement, $$$B/d$$$. The count_ways function uses a "Stars and Bars" formula to find the number of ways to form both $$$d$$$ and $$$B/d$$$ from $$$N$$$ multipliers. These two counts are multiplied and added to the total answer.
#include <bits/stdc++.h>
using namespace std;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM =
chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
#define prDouble(x) cout<<fixed<<setprecision(10)<<x
#define fastio() ios::sync_with_stdio(false); cin.tie(nullptr)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
using ll = long long;
using ld = long double;
using pll = pair<ll,ll>;
using tll = tuple<ll,ll,ll>;
using vll = vector<ll>;
using vpll = vector<pll>;
vector<ll> dx = {1, -1, 0, 0}, dy = {0, 0, 1, -1}; // for grid
vector<ll> ddx = {1,1,0,-1,-1,-1,0,1}, ddy = {0,1,1,1,0,-1,-1,-1}; // 8 directions
template<typename T> void read(vector<T> &v) { for (auto &x : v) cin >> x; }
template<typename T> void printv(const vector<T>& v) { for (auto &x : v) cout << x << ' '; }
template<typename T> void print2d(const vector<vector<T>>& v) { for (auto &row : v) { for (auto &x : row) cout << x << ' '; cout << '\n'; } }
ll t=1,n,m,p,q,r,k,a,b,c,x,y,z;
const ll INF = 1e18, MOD = 1e9+7;
const ll MAX_EXP = 65;
ll fact[MAX_EXP];
ll invFact[MAX_EXP];
ll N_val, A_val;
vector<pair<ll, int>> pf_B;
vector<pair<ll, int>> pf_d;
ll total_ans;
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;
}
ll modInverse(ll n) {
return power(n, MOD - 2);
}
void precompute_factorials() {
fact[0] = 1;
invFact[0] = 1;
for (int i = 1; i < MAX_EXP; i++) {
fact[i] = (fact[i - 1] * i) % MOD;
invFact[i] = modInverse(fact[i]);
}
}
ll combinations(int k, ll N) {
if (k < 0) return 0;
if (k == 0) return 1;
ll N_mod = N % MOD;
ll num = 1;
for (int i = 0; i < k; ++i) {
num = (num * ((N_mod + i) % MOD)) % MOD;
}
return (num * invFact[k]) % MOD;
}
ll count_ways(const vector<pair<ll, int>>& prime_factors, ll N) {
ll res = 1;
for (auto const& [p, e] : prime_factors) {
res = (res * combinations(e, N)) % MOD;
}
return res;
}
void generate_divisors_and_calculate(int k, ll current_d) {
if (k == (int)pf_B.size()) {
if (current_d > A_val) {
return;
}
vector<pair<ll, int>> pf_comp;
for (size_t i = 0; i < pf_B.size(); ++i) {
if (pf_B[i].second - pf_d[i].second > 0) {
pf_comp.push_back({pf_B[i].first, pf_B[i].second - pf_d[i].second});
}
}
ll ways1 = count_ways(pf_d, N_val);
ll ways2 = count_ways(pf_comp, N_val);
total_ans = (total_ans + (ways1 * ways2) % MOD) % MOD;
return;
}
ll p = pf_B[k].first;
int max_exp = pf_B[k].second;
ll p_power = 1;
for (int i = 0; i <= max_exp; ++i) {
if ((double)A_val / p_power < current_d) {
break;
}
pf_d.push_back({p, i});
generate_divisors_and_calculate(k + 1, current_d * p_power);
pf_d.pop_back();
if (i < max_exp) {
p_power *= p;
}
}
}
void solve() {
ll B_val;
cin >> N_val >> A_val >> B_val;
pf_B.clear();
ll temp_B = B_val;
for (ll i = 2; i * i <= temp_B; ++i) {
if (temp_B % i == 0) {
int count = 0;
while (temp_B % i == 0) {
temp_B /= i;
count++;
}
pf_B.push_back({i, count});
}
}
if (temp_B > 1) {
pf_B.push_back({temp_B, 1});
}
total_ans = 0;
pf_d.clear();
generate_divisors_and_calculate(0, 1);
cout << total_ans << "\n";
}
int main() {
fastio();
precompute_factorials();
cin >> t;
for (int i = 1; i <= t; ++i) {
cout << "Case #" << i << ": ";
solve();
}
return 0;
}
A subarray is flattenable if and only if its total XOR sum is 0. Since checking all $$$O(N^2)$$$ subarrays is too slow, use an $$$O(N)$$$ "sum of lengths minus correction" method. Calculate the total sum of all subarray lengths, then subtract a "discount" for all flattenable (zero-sum) subarrays.
The code builds a prefix XOR array p (with p[0]=0) and uses a hash map to count the frequency k of each prefix XOR value. It computes the total sum of all subarray lengths, $$$\frac{N(N+1)(N+2)}{6}$$$, and then subtracts the total "correction" $$$\sum \frac{k(k-1)(k+1)}{6}$$$ for each frequency $$$k \gt 1$$$.
#include <bits/stdc++.h>
using namespace std;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM =
chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
#define prDouble(x) cout<<fixed<<setprecision(10)<<x
#define fastio() ios::sync_with_stdio(false); cin.tie(nullptr)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
using ll = long long;
using ld = long double;
using pll = pair<ll,ll>;
using tll = tuple<ll,ll,ll>;
using vll = vector<ll>;
using vpll = vector<pll>;
vector<ll> dx = {1, -1, 0, 0}, dy = {0, 0, 1, -1}; // for grid
vector<ll> ddx = {1,1,0,-1,-1,-1,0,1}, ddy = {0,1,1,1,0,-1,-1,-1}; // 8 directions
template<typename T> void read(vector<T> &v) { for (auto &x : v) cin >> x; }
template<typename T> void printv(const vector<T>& v) { for (auto &x : v) cout << x << ' '; }
template<typename T> void print2d(const vector<vector<T>>& v) { for (auto &row : v) { for (auto &x : row) cout << x << ' '; cout << '\n'; } }
ll t=1,n,m,p,q,r,k,a,b,c,x,y,z;
const ll INF = 1e18, MOD = 1e9+7;
void solve() {
cin >> n;
vector<int> a(n);
read(a);
vector<int> p(n + 1, 0);
for (int i = 0; i < n; ++i) {
p[i + 1] = p[i] ^ a[i];
}
unordered_map<int, ll> counts;
for (int val : p) {
counts[val]++;
}
ll N = n;
ll total_length_sum = N * (N + 1) * (N + 2) / 6;
ll total_correction = 0;
for (auto const& [val, k] : counts) {
if (k > 1) {
total_correction += k * (k - 1) * (k + 1) / 6;
}
}
ll total_cost = total_length_sum - total_correction;
cout << total_cost << "\n";
}
int main() {
fastio();
cin >> t;
for (ll i = 1; i <= t; ++i) {
cout << "Case #" << i << ": ";
solve();
}
return 0;
}
Analyze the game by compressing the string into blocks (e.g., AABBA -> (2,'A'), (2,'B'), (1,'A')). This is a game on these blocks. Consider the terminal states. What happens if the very last block on the table is an 'A'? Can Bob ever eat it or destroy it with his move?
The code implements a recursive game-state reduction.
Compression: The string S is first compressed into a vector of blocks (e.g., AABBB becomes {{2, 'A'}, {3, 'B'}}).
Winning Condition: The code's core logic is in the while loop. In each step, it checks: if (blocks.back().s == 0) (i.e., if the last block is 'A'). This is an immediate win for Alice. Why? Bob's moves only destroy suffixes that start with 'B'. He has no move that can touch or destroy a final 'A' block. Alice can therefore bide her time. On any of her turns, she can choose to eat the very last 'A' plate, winning the game.
Game Reduction: If the last block is 'B', the game continues. The code simulates one full "round" of the game (an Alice move + a Bob move) by creating a new list of blocks. It iterates through all current blocks and subtracts 1 from their count (a.f — 1). Blocks with a count of 1 are removed entirely. This reduction (a.f — 1) is a non-trivial insight, representing the effect of one round on the game state. Adjacent blocks of the same type are merged.
Final State: The loop repeats until only one block (or zero) is left. If the last remaining block is 'A', Alice wins (by the same logic as step 2). If no blocks are left, it means Alice was unable to force a win, so Bob wins.
#include "bits/stdc++.h"
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
using namespace std;
typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;
typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;
typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;
template<class T> using pq = priority_queue<T>;
template<class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a,x) for (auto& a : x)
#define uid(a, b) uniform_int_distribution<int>(a, b)(rng)
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define ins insert
template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}
template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ", "; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? ", " : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifdef DEBUG
#define dbg(x...) cerr << "\e[91m"<<__func__<<":"<<__LINE__<<" [" << #x << "] = ["; _print(x); cerr << "\e[39m" << endl;
#else
#define dbg(x...)
#endif
const int MOD = 1000000007;
const char nl = '\n';
const int MX = 100001;
void solve() {
int N; cin >> N;
vpi blocks;
string S; cin >> S;
int cnt = 1;
char C = S[0];
FOR(i, 1, sz(S)) {
if (S[i] != C) {
blocks.pb({cnt, C-'A'});
cnt = 0;
C = S[i];
}
cnt++;
}
blocks.pb({cnt, C-'A'});
while (sz(blocks) > 1) {
if (blocks.back().s == 0) {
cout << "Alice" << nl; return;
}
vpi nb;
trav(a, blocks) {
if (a.f > 1) {
if (sz(nb) == 0 || nb.back().s != a.s) {
nb.pb({a.f-1, a.s});
} else {
nb.back().f += a.f - 1;
}
}
}
blocks = nb;
//dbg(blocks);
}
if (sz(blocks) && blocks[0].s == 0) {
cout << "Alice" << nl;
} else {
cout << "Bob" << nl;
}
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int t;
cin >> t;
FOR(i, 1, t+1) {
cout << "Case #" << i << ": ";
solve();
}
return 0;
}
Final Thoughts
This round was an amazing experience—every problem had something new to learn:
- Snakes Scales (A1, A2): A great ramp-up from simple iteration to a classic Binary Search + BFS/DFS.
- Final Product (B1, B2): A fun test of mathematical insight, scaling from a simple construction to complex Number Theory and Combinatorics.
- Narrowing Down (C): A clever $$$O(N)$$$ solution requiring a key insight with prefix XORs and a tricky counting formula.
- Crash Course (D): A very deceptive game theory problem with a non-obvious optimal strategy.
I’ll soon be posting about Round 2 as well—stay tuned!
If you found this helpful, feel free to leave feedback or share your approaches below in the comments Contact me at LinkedIn or Github







