π§© AtCoder Beginner Contest 369
π§© AtCoder Beginner Contest 369
# Info & Summary
- Date:
2024-08-31
- Completion Status: A β / B β / C β / D β / E β / F β / G β
- Problem Type:
Problem | Type(s) | Data Structure / Algo | π₯ Key Insight / Mark |
---|---|---|---|
D | Maximum value | DP | βπ₯π§ |
E | Shortest Path | DP & Warshall-Floyed | π§ π |
F | longest increasing subsequence(LIS) | LIS | π |
G | Tree DP | Tree DP | π |
Details
Emoji | Label | Meaning |
---|---|---|
β | Important | Problem is strategically useful or has reusable patterns |
π₯ | Must master | Classic problem or technique that appears often and is worth mastering |
β οΈ | Reattempt | You attempted but failed; worth reviewing and solving again |
π§ | New to me | Introduced a new idea, technique, or pattern you hadnβt seen before |
π οΈ | Template | You built or improved a code template from solving this problem |
π | Too hard now | Beyond current ability to understand/solve; revisit after more practice |
π A - 369

#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int A, B;
cin >> A >> B;
if (A > B)
{
swap(A, B);
}
set<int> s;
s.insert(A - (B - A));
if ((B - A) % 2 == 0)
{
s.insert(A + (B - A) / 2);
}
s.insert(B + (B - A));
cout << s.size() << endl;
return 0;
}
π B - Piano 3

#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
int ans = 1e9;
vector<int> A(N);
vector<char> P(N);
for (int i = 0; i < N; i++)
{
cin >> A[i] >> P[i];
}
for (int l = 1; l <= 100; l++)
{
for (int r = 1; r <= 100; r++)
{
int temp = 0;
int left = l, right = r;
for (int i = 0; i < N; i++)
{
if (P[i] == 'L')
{
temp += abs(A[i] - left);
left = A[i];
}
else
{
temp += abs(A[i] - right);
right = A[i];
}
}
ans = min(ans, temp);
}
}
cout << ans << endl;
return 0;
}
π C - Count Arithmetic Subarrays

#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
vector<int> A(N);
for (int i = 0; i < N; i++)
{
cin >> A[i];
}
long long ans = 0;
for (int l = 0, r = 0; l < N; l++)
{
while (r + 1 < N && A[r + 1] - A[r] == A[l + 1] - A[l])
{
r++;
}
ans += r - l + 1;
}
cout << ans << endl;
return 0;
}
π D - Bonus EXP

Tips
Let:
: the maximum total experience point when defeating an even number of monsters out of the first monsters to encountered, and be that for an odd number of monsters, or if it is impossible
Initially,
Tips
Here, for , note that the experience point that can be gained from the -th monster is solely dependent on:
- whether Takahashi chose to defeat it or let it go; and
- (if he decided to defeat it)whether the number of monsters defeated so far is even or odd
Also, to encounter the first monsters and defeat an even number of monsters, the following two cases are only possible:
- defeat an even number of monsters among the first , and let the -th go; or
- defeat an odd number of monsters among the first , and defeat the -th
Therefore, if we know and , we can find:
The final answer is:
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
vector<long long> A(N);
for (int i = 0; i < N; i++)
{
cin >> A[i];
}
vector<long long> dp(2);
dp[0] = 0ll;
dp[1] = -1e18;
for (int i = 0; i < N; i++)
{
vector<long long> nxt = dp;
nxt[0] = max(dp[0], dp[1] + 2 * A[i]);
nxt[1] = max(dp[1], dp[0] + A[i]);
dp = nxt;
}
cout << max(dp[0], dp[1]) << endl;
return 0;
}
π E - Sightseeing Tour

Tips
First of all, let be the time required to travel from island to without any constraints
This can be computed for all pairs of islands in a total time using Warshall-Floyed
algorithm
Tips
Consider solving the -th problem, the bridges connect islands
Fix the order of using those bridges and the directions. When the bridges are decided to be used in the order and directions of , then the minimum time required to travel from island to island subject to the condition is:
The final answer is the minimum of this value for all order and directions
Tips
- if we precompute , this can be found as the sum of numbers
- fix the order of using those bridges:
- fix the directions:
If we use dynamic programming once the order is fixed, the time required to solve one question becomes about: , which enables us to solve the problem faster
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M;
cin >> N >> M;
vector<vector<long long>> dis(N, vector<long long>(N, 1e18));
for (int i = 0; i < N; i++)
{
dis[i][i] = 0;
}
vector<long long> U(M), V(M), T(M);
for (int i = 0; i < M; i++)
{
cin >> U[i] >> V[i] >> T[i];
U[i]--;
V[i]--;
dis[U[i]][V[i]] = min(dis[U[i]][V[i]], T[i]);
dis[V[i]][U[i]] = dis[U[i]][V[i]];
}
for (int k = 0; k < N; k++)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
}
}
}
int Q;
cin >> Q;
while (Q--)
{
int K;
cin >> K;
vector<int> B(K);
for (int i = 0; i < K; i++)
{
cin >> B[i];
B[i]--;
}
sort(B.begin(), B.end());
long long ans = 1e18;
do
{
array<long long, 2> dp = {dis[0][V[B[0]]] + T[B[0]], dis[0][U[B[0]]] + T[B[0]]};
for (int i = 1; i < K; i++)
{
int a = B[i - 1];
int b = B[i];
dp = {min(dp[0] + dis[U[a]][V[b]], dp[1] + dis[V[a]][V[b]]) + T[b], min(dp[0] + dis[U[a]][U[b]], dp[1] + dis[V[a]][U[b]]) + T[b]};
}
ans = min({ans, dp[0] + dis[U[B[K - 1]]][N - 1], dp[1] + dis[V[B[K - 1]]][N - 1]});
} while (next_permutation(B.begin(), B.end()));
cout << ans << endl;
}
return 0;
}
π F - Gather Coins

Warning
Hard Problems to Tackle Later
// TODO
π G - As far as possible

Warning
Hard Problems to Tackle Later
// TODO