Three-Point Search and Substring Analysis for AtCoder ABC 043

Problem A

Compute the sum \(\sum_{i=1}^{n} i = \binom{n+1}{2}\).

Problem B

Statement:
Given a string, process it from left to right. Whenever a character B is encountered, it removes itself and the character immediately to its right (if any). Output the final remaining string.

Solution:
Use a stack-like approach: iterate over the input and push non-B characters onto a result string. When B is seen, pop the last character from the result if it exists.

std::string s; std::cin >> s;
std::string ans = "";
for (int i = 0; i < s.size(); i++) {
    if (s[i] == 'B') {
        if (!ans.empty()) ans.pop_back();
    } else {
        ans.push_back(s[i]);
    }
}
std::cout << ans << "\n";

Problem C

Statement:
Given an array \(a_1, a_2, \dots, a_n\), find a value \(x\) that minimizes the total cost \(\sum (a_i - x)^2\). The constraints are small: \(-100 \le a_i \le 100\).

Solution:
The objective function is a convex quadratic: \(\sum (a_i - x)^2 = n x^2 - 2x\sum a_i + \sum a_i^2\). Hence ternary search works to find the minimum over real numbers. Alternatively, since the domain is small, one may brute-force all integers between the minimum and maximum of the array.

Let \(M\), \(m\) be the maximum and minimum of \(a_i\). Any \(x\) outside \([m, M]\) is suboptimal: moving \(x\) to the nearest bound reduces the cost. Therefore the optimal \(x\) lies in \([m, M]\).

For the general case (large \(a_i\)), ternary search is appropriate:

int n;
std::vector<int> a(n);
// read a
int lo = *std::min_element(a.begin(), a.end());
int hi = *std::max_element(a.begin(), a.end());
while (hi - lo > 3) {
    int m1 = lo + (hi - lo) / 3;
    int m2 = hi - (hi - lo) / 3;
    long long f1 = 0, f2 = 0;
    for (int v : a) {
        f1 += (v - m1) * (v - m1);
        f2 += (v - m2) * (v - m2);
    }
    if (f1 < f2) hi = m2;
    else lo = m1;
}
long long ans = 1LL << 60;
for (int x = lo; x <= hi; ++x) {
    long long cur = 0;
    for (int v : a) cur += (v - x) * (v - x);
    ans = std::min(ans, cur);
}
std::cout << ans << "\n";

Problem D

Statement:
A string is called unbalanced if its length is at least 2 and some character apppears more then half the length. Given a string \(s\) (length up to \(10^5\)), find the start and end indices (1‑based) of any unbalanced substring, or output -1 -1 if none exists.

Solution:
If an unbalanced substring exists, then by repeatedly removing one character from each end (preserving the property) we eventually obtain a substring of length 2 or 3 that remains unbalanced. Therefore it suffices to check all substrings of lengths 2 and 3.

  • For length 2: the two characters must be equal.
  • For length 3: at least two of the three characters must be equal.
std::string s; std::cin >> s;
int n = s.size();
for (int i = 0; i < n - 1; ++i) {
    if (s[i] == s[i+1]) {
        std::cout << i+1 << " " << i+2 << "\n";
        return 0;
    }
}
for (int i = 0; i < n - 2; ++i) {
    char a = s[i], b = s[i+1], c = s[i+2];
    if (a == b || a == c || b == c) {
        std::cout << i+1 << " " << i+3 << "\n";
        return 0;
    }
}
std::cout << -1 << " " << -1 << "\n";

Tags: Competitive Programming AtCoder ternary search string stack

Posted on Wed, 13 May 2026 10:36:54 +0000 by jswinkelman