Solutions for AtCoder Beginner Contest 369 Problems

The sample cases cover all possible scenarios for this problem.

int main() { int x, y; cin >> x >> y; int result = 0;

if(x > y) swap(x, y);
if(x == y) result = 1;
else if((y - x) % 2) result = 2;
else result = 3;

cout << result << endl;
return 0;

}


</details>### Problem B - Piano Keys

Track positions for left and right hands separate and simulate the movements.

<details><summary>View Solution Code</summary>```
#include<iostream>
#include<cmath>
using namespace std;

int main() {
    int n, left_pos = 0, right_pos = 0, total = 0;
    cin >> n;
    
    while(n--) {
        int pos; string hand;
        cin >> pos >> hand;
        
        if(hand == "L") {
            if(!left_pos) left_pos = pos;
            total += abs(left_pos - pos);
            left_pos = pos;
        }
        else {
            if(!right_pos) right_pos = pos;
            total += abs(right_pos - pos);
            right_pos = pos;
        }
    }
    cout << total << endl;
    return 0;
}

Key observation: All subarrays of an arithmetic sequence are also arithmetic sequences.

Use two pointers to find maximal arithmetic subarrays and calculate the number of valid subarrays within them.

#include<iostream>
using namespace std;

const int MAX = 2e5+5;
int arr[MAX];

int main() {
    int n;
    cin >> n;
    for(int i=0; i<n; i++) cin >> arr[i];
    
    long long count = 0;
    int left = 0, right = 0;
    
    for(left=0; left<n; left=right) {
        for(right=left+1; right<n; right++) {
            if(arr[right+1] - arr[right] != arr[right] - arr[right-1]) break;
        }
        int length = right - left + 1;
        count += (1LL * (1 + length) * length) / 2 - 1;
    }
    cout << count + 1 << endl;
    return 0;
}

Problem D - Experience Points

Dynamic Programming solution with two states tracking even/odd selections.

Transition equations:

f[0][i] = max(f[0][i-1], f[1][i-1] + 2*a[i])

f[1][i] = max(f[1][i-1], f[0][i-1] + a[i])

Problem E - Tour Planning

Precompute all-pairs shortest paths using Floyd-Warshall algorithm.

For each query, evaluate all possible permutations of edges and directions to find the minimal path.

#include<iostream>
#include<algorithm>
#include<climits>
using namespace std;

const int N = 405;
long long dist[N][N];
int n, m;

void floyd() {
    for(int k=1; k<=n; k++)
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}

int main() {
    cin >> n >> m;
    fill(&dist[0][0], &dist[0][0]+N*N, INT_MAX);
    
    for(int i=0; i<m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        dist[u][v] = dist[v][u] = w;
    }
    floyd();
    
    int q;
    cin >> q;
    while(q--) {
        int k;
        cin >> k;
        vector<int> edges(k);
        for(int i=0; i<k; i++) cin >> edges[i];
        
        long long min_path = LONG_MAX;
        do {
            for(int mask=0; mask<(1<<k); mask++) {
                vector<int> nodes;
                long long current = 0;
                
                for(int i=0; i<k; i++) {
                    int u = edges[i]/1000, v = edges[i]%1000;
                    if(mask & (1<<i)) swap(u, v);
                    nodes.push_back(u);
                    nodes.push_back(v);
                }
                
                current += dist[1][nodes[0]];
                for(int i=0; i<k*2; i+=2) {
                    current += dist[nodes[i+1]][nodes[i+2]];
                }
                current += dist[nodes.back()][n];
                
                min_path = min(min_path, current);
            }
        } while(next_permutation(edges.begin(), edges.end()));
        
        cout << min_path << endl;
    }
    return 0;
}

Problem F - Coin Collection

Transform the problem into finding the longest non-decreasing subsequence of column coordinates.

Use a Binary Indexed Tree to efficiently compute the maximum sequence length.

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

struct BIT {
    vector<pair<int,int>> tree;
    BIT(int size) : tree(size+1) {}
    
    void update(int idx, pair<int,int> val) {
        for(; idx<tree.size(); idx += idx&-idx)
            tree[idx] = max(tree[idx], val);
    }
    
    pair<int,int> query(int idx) {
        pair<int,int> res = {0,0};
        for(; idx; idx -= idx&-idx)
            res = max(res, tree[idx]);
        return res;
    }
};

int main() {
    int h, w, n;
    cin >> h >> w >> n;
    vector<pair<int,int>> coins(n+2);
    
    for(int i=1; i<=n; i++) cin >> coins[i].first >> coins[i].second;
    coins[n+1] = {1,1};
    coins[n+2] = {h,w};
    sort(coins.begin(), coins.end());
    
    BIT bit(w);
    vector<int> dp(n+3), prev(n+3);
    
    for(int i=1; i<=n+2; i++) {
        auto res = bit.query(coins[i].second);
        dp[i] = res.first + 1;
        prev[i] = res.second;
        bit.update(coins[i].second, {dp[i], i});
    }
    
    vector<int> path;
    for(int i=n+2; i; i=prev[i]) path.push_back(i);
    reverse(path.begin(), path.end());
    
    cout << path.size()-2 << endl;
    return 0;
}

Tags: AtCoder competitive-programming algorithm dynamic-programming graph-theory

Posted on Wed, 21 Oct 2026 16:54:36 +0000 by peyups