Solutions to Educational Codeforces Round 162

This problem requires counting the number of zeros between the first and last occurrence of 1 in an array.


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve() {
    int n;
    cin >> n;
    vector<int> arr(n);
    int firstOne = -1, lastOne = -1;
    
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
        if (arr[i] == 1) {
            if (firstOne == -1) firstOne = i;
            lastOne = i;
        }
    }
    
    if (firstOne == -1) {
        cout << 0 << '\n';
        return;
    }
    
    int zeroCount = 0;
    for (int i = firstOne + 1; i < lastOne; i++) {
        if (arr[i] == 0) zeroCount++;
    }
    
    cout << zeroCount << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int queries;
    cin >> queries;
    while (queries--) {
        solve();
    }
    return 0;
}

Problem B: Monster Battle Strategy

This problem involves determining if monsters can be defeated by attacking from closest to farthest, using a greedy approach with prefix sums.


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Monster {
    ll health;
    ll position;
};

void solve() {
    ll monsterCount, attackPower;
    cin >> monsterCount >> attackPower;
    
    vector<ll> healths(monsterCount);
    vector<ll> positions(monsterCount);
    
    for (int i = 0; i < monsterCount; i++) {
        cin >> healths[i];
    }
    
    for (int i = 0; i < monsterCount; i++) {
        cin >> positions[i];
        positions[i] = abs(positions[i]);
    }
    
    vector<Monster> monsters;
    for (int i = 0; i < monsterCount; i++) {
        monsters.push_back({healths[i], positions[i]});
    }
    
    sort(monsters.begin(), monsters.end(), [](const Monster& a, const Monster& b) {
        return a.position < b.position;
    });
    
    ll cumulativeHealth = 0;
    bool possible = true;
    
    for (const auto& monster : monsters) {
        cumulativeHealth += monster.health;
        if (cumulativeHealth > monster.position * attackPower) {
            possible = false;
            break;
        }
    }
    
    cout << (possible ? "YES" : "NO") << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int testCases;
    cin >> testCases;
    while (testCases--) {
        solve();
    }
    return 0;
}

Problem C: String Trensformation

This problem deals with transforming strings based on specific rules and determining if a transformation is possible.


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve() {
    int n, q;
    cin >> n >> q;
    string s;
    cin >> s;
    
    vector<ll> prefixSum(n + 1, 0);
    vector<ll> zeroCount(n + 1, 0);
    
    for (int i = 0; i < n; i++) {
        prefixSum[i + 1] = prefixSum[i] + (s[i] - '0');
        zeroCount[i + 1] = zeroCount[i] + (s[i] == '0' ? 1 : 0);
    }
    
    while (q--) {
        int l, r;
        cin >> l >> r;
        l--, r--;
        
        if (l == r) {
            cout << "YES\n";
            continue;
        }
        
        ll totalDigits = r - l + 1;
        ll ones = prefixSum[r + 1] - prefixSum[l];
        ll zeros = zeroCount[r + 1] - zeroCount[l];
        
        // Check if the transformation is possible
        if (ones >= 4 && (ones - 4) * 2 <= totalDigits) {
            cout << "YES\n";
        } else {
            cout << "NO\n";
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int testCases;
    cin >> testCases;
    while (testCases--) {
        solve();
    }
    return 0;
}

Problem D: Binary Search with Prefix Sums

This problem requires finding the minimum number of operations to transform an array using preprocessing and binary search with prefix sums.


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll INF = (1ll << 60);

void solve() {
    int n;
    cin >> n;
    vector<ll> arr(n), result(n, INF);
    vector<ll> prefix(n + 1, 0);
    vector<ll> lastDiff(n + 1, 0);
    
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
        prefix[i + 1] = prefix[i] + arr[i];
    }
    
    // Preprocess last different position
    for (int i = 1; i <= n; i++) {
        lastDiff[i] = (arr[i - 1] == arr[i - 2]) ? lastDiff[i - 1] : i - 1;
    }
    
    // Left to right pass
    for (int i = 0; i < n; i++) {
        if (i > 0 && arr[i] < arr[i - 1]) {
            result[i] = 1;
            continue;
        }
        
        ll left = 0, right = lastDiff[i + 1];
        while (left <= right) {
            ll mid = (left + right) / 2;
            ll sum = prefix[i + 1] - prefix[mid];
            if (sum > arr[i]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        
        if (left <= i) {
            result[i] = min(result[i], i - left + 1);
        }
        if (right >= 0) {
            result[i] = min(result[i], i - right);
        }
    }
    
    // Right to left pass
    reverse(arr.begin(), arr.end());
    for (int i = 0; i <= n; i++) {
        prefix[i] = 0;
        lastDiff[i] = 0;
    }
    
    for (int i = 1; i <= n; i++) {
        prefix[i] = prefix[i - 1] + arr[i - 1];
    }
    
    for (int i = 1; i <= n; i++) {
        lastDiff[i] = (arr[i - 1] == arr[i - 2]) ? lastDiff[i - 1] : i - 1;
    }
    
    for (int i = 0; i < n; i++) {
        if (i > 0 && arr[i] < arr[i - 1]) {
            result[n - i - 1] = min(result[n - i - 1], 1ll);
            continue;
        }
        
        ll left = 0, right = lastDiff[i + 1];
        while (left <= right) {
            ll mid = (left + right) / 2;
            ll sum = prefix[i + 1] - prefix[mid];
            if (sum > arr[i]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        
        if (left <= i) {
            result[n - i - 1] = min(result[n - i - 1], i - left + 1);
        }
        if (right >= 0) {
            result[n - i - 1] = min(result[n - i - 1], i - right);
        }
    }
    
    for (int i = 0; i < n; i++) {
        cout << (result[i] == INF ? -1 : result[i]) << " ";
    }
    cout << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int testCases;
    cin >> testCases;
    while (testCases--) {
        solve();
    }
    return 0;
}

Tags: Codeforces competitive-programming binary-search prefix-sum greedy

Posted on Wed, 07 Oct 2026 16:56:53 +0000 by basil