Problem A
Problem Statement
Given two integers S and T where S ≤ T, determine the count of positive integers within the inclusive range [S, T].
Approach
The number of integers in a contiguous sequence from S to T is calculated directly by subtracting the start value from the end value and adding one. The formula is simply T - S + 1.
Code Implementation
#include <iostream>
void solve() {
int s, t;
std::cin >> s >> t;
int result = t - s + 1;
std::cout << result << "\n";
}
int main() {
solve();
return 0;
}
Problem B
Problem Statement
Given n strings, identify which character appears most frequently across all of them.
Approach
To efficiently track character counts without high overhead from string comparisons, we can utilize double hashing. Instead of inserting raw strings into a map, we compute a pair of hash values for each unique string. This reduces memory usage and comparison costs.
Key steps include:
- Compute two polynomial rolling hashes for each string using different bases and moduli.
- Store the hash pair as a key in a frequency map.
- Track the maximum frequency encountered during insertion.
- Maintain a secondary mapping from the hash key back to the original string for retrieval.
Code Implementation
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
const int MOD1 = 1e9 + 7;
const int BASE1 = 131;
const int MOD2 = 1e9 + 9;
const int BASE2 = 137;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n;
if (!(cin >> n)) return 0;
map<pair<long long, long long>, int> freq;
map<pair<long long, long long>, string> lookup;
int max_count = 0;
pair<long long, long long> best_key = {0, 0};
for (int i = 0; i < n; ++i) {
string s;
cin >> s;
long long h1 = 0, h2 = 0;
for (char c : s) {
h1 = (h1 * BASE1 + c) % MOD1;
h2 = (h2 * BASE2 + c) % MOD2;
}
pair<long long, long long> key = {h1, h2};
freq[key]++;
if (freq[key] > max_count) {
max_count = freq[key];
best_key = key;
}
if (lookup.find(key) == lookup.end()) {
lookup[key] = s;
}
}
cout << lookup[best_key] << endl;
return 0;
}
Problem C
Problem Statement
There are n coins with values a_1, ..., a_n. Initially, all coins are heads up. For every coin at index i (from left to right), flip all subsequent coins j (where j > i) if a_j is a multiple of a_i. Calculate the expected number of heads remaining after this process.
Approach
Calculating permutations for small N (N ≤ 8) allows direct simulation. However, for larger N, we leverage Linearity of Expectation.
For a specific coin at position i with value v, it remains heads up if an even number of coins to its left have values that divide v (including itself). If there are k divisors in the array including the current one, the probability depends on the parity of the position among these specific elements.
Specifically, if a coin has k related items (divisors), the probability it ends up heads is ceil(k / 2) / k. We sum these probabilities over all coins.
Code Implementation
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; ++i) cin >> a[i];
double expected_heads = 0.0;
for (int i = 0; i < n; ++i) {
int divisor_count = 0;
for (int j = 0; j < n; ++j) {
// Check divisibility condition
if (a[i] % a[j] == 0) {
divisor_count++;
}
}
// Probability calculation based on divisor count
// Number of heads contribution is ceil(count/2) / count
double prob = ((double)(divisor_count + 1) / 2) / divisor_count;
expected_heads += prob;
}
cout.precision(10);
cout << fixed << expected_heads << endl;
return 0;
}
Problem D
Problem Statement
Consider a grid of width W and height H containing gold blocks. There are N collectors located at specific coordinates. Collectors expand outward in four cardinal directions collecting available blocks until they stop. Determine the maximum number of gold blocks collected by arranging the order of collector expansion optimally.
Approach
This problem can be modeled using Dynamic Programming with memoization on rectangular regions.
A state is defined by a rectangle bounded by (x1, y1) and (x2, y2). To calculate the optimal collection for a region, we iterate through all collectors inside the current rectangle. Each collector acts as a pivot, splitting the rectangle into four smaller sub-rectangles (top-left, top-right, bottom-left, bottom-right). The score for choosing a pivot is the perimeter length of the expanded arms plus the recursive results of the four sub-regions.
Since only rectangles formed by coordinate boundaires matter, the state space is optimized significantly compared to full grid DP.
Code Implementation
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <functional>
using namespace std;
int W, H, N;
struct Point { int x, y; };
vector<Point> collectors;
map<vector<int>, int> memo;
int solve_region(int x1, int y1, int x2, int y2) {
vector<int> state = {x1, y1, x2, y2};
if (memo.count(state)) return memo[state];
int max_val = 0;
// Iterate over collectors located within this bounding box
for (const auto& p : collectors) {
if (p.x >= x1 && p.x <= x2 && p.y >= y1 && p.y <= y2) {
// Calculate score: Perimeter contribution + Recursive splits
int current_score = (x2 - x1 + 1) + (y2 - y1 + 1) - 1;
current_score += solve_region(x1, y1, p.x - 1, p.y - 1);
current_score += solve_region(p.x + 1, y1, x2, p.y - 1);
current_score += solve_region(x1, p.y + 1, p.x - 1, y2);
current_score += solve_region(p.x + 1, p.y + 1, x2, y2);
max_val = max(max_val, current_score);
}
}
return memo[state] = max_val;
}
int main() {
cin >> W >> H >> N;
collectors.resize(N);
for (int i = 0; i < N; ++i) {
cin >> collectors[i].x >> collectors[i].y;
}
int result = solve_region(1, 1, W, H);
cout << result << endl;
return 0;
}