ABC 315
Table of Contents
https://atcoder.jp/contests/abc315
A. tcdr
https://atcoder.jp/contests/abc315/tasks/abc315_a
B. The Middle Day
https://atcoder.jp/contests/abc315/tasks/abc315_b
C. Flavors
https://atcoder.jp/contests/abc315/tasks/abc315_c
D. Magical Cookies
https://atcoder.jp/contests/abc315/tasks/abc315_d
2026/2/11 解説 AC
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll H, W;
cin >> H >> W;
vvint grid(H, vint(W));
rep(i, H) rep(j, W) {
char c;
cin >> c;
grid[i][j] = c - 'a';
}
vvint rows(H, vint(26)), cols(W, vint(26));
rep(i, H) rep(j, W) {
rows[i][grid[i][j]]++;
cols[j][grid[i][j]]++;
}
using T = tuple<ll, ll, ll>;
vint delr(H), delc(W);
int nr = H, nc = W;
while (true) {
vector<T> v;
rep(i, H) rep(c, 26) {
if (rows[i][c] == nc && rows[i][c] > 1) v.push_back({0, i, c});
}
rep(j, W) rep(c, 26) {
if (cols[j][c] == nr && cols[j][c] > 1) v.push_back({1, j, c});
}
for (auto [t, i, c] : v) {
if (t == 0) {
delr[i] = 1;
rows[i][c] = 0;
rep(j, W) {
if (delc[j]) continue;
cols[j][c]--;
}
nr--;
} else {
delc[i] = 1;
cols[i][c] = 0;
rep(r, H) {
if (delr[r]) continue;
rows[r][c]--;
}
nc--;
}
}
if (v.size() == 0) break;
}
cout << nr * nc << endl;
}
E. Prerequisites
https://atcoder.jp/contests/abc315/tasks/abc315_e
2026/2/11 自力 AC
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N;
cin >> N;
vvll graph(N);
rep(i, N) {
ll c;
cin >> c;
rep(j, c) {
int v;
cin >> v;
v--;
graph[i].push_back(v);
}
}
vint visited(N);
auto dfs = [&](auto dfs, int now, vint& ans) -> void {
if (visited[now]) return;
visited[now] = 1;
for (int nx : graph[now]) {
dfs(dfs, nx, ans);
}
ans.push_back(now + 1);
};
vint ans;
dfs(dfs, 0, ans);
ans.pop_back();
print(ans);
}
F. Shortcuts
https://atcoder.jp/contests/abc315/tasks/abc315_f
2026/2/24 自力 AC
省略せずに移動した場合での総距離はたかだか $\sqrt{(10^4)^2 + (10^4)^2} \times 10^4 = 1.4 \times 10^8$ なので、 30回も省略すればそれだけで $2^{30-1} = 2^{29} = 536,870,912 \sim 5.4 \times 10^8$ のペナルティを受けるので、省略はせいぜい30回程度まで考えれば十分。
$dp(i,c)$ を「チェックポイント $i$ に到達するまでに $c$ 個のチェックポイントを省略したときの総移動距離の最小値」と定義する。
\begin{align*} dp(i, c) = \min_{0 \leq skip < C} dp(i - skip - 1, c - skip) + \text{dist}(i, i - skip - 1) \end{align*}
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N;
cin >> N;
vll X(N), Y(N);
rep(i, N) cin >> X[i] >> Y[i];
int C = 31;
// dp[i][j]: チェックポイント i に到達するまでに j 個のチェックポイントをスキップしたときの総移動距離の最小値
vector dp(N, vector<double>(C, (double)INF));
dp[0][0] = 0;
rep(i, N) {
rep(j, C) {
for (int skip = C - 1; skip >= 0; skip--) {
int ni = i + skip + 1;
int ns = j + skip;
if (ni >= N) continue;
if (ns >= C) continue;
ll dx = X[ni] - X[i];
ll dy = Y[ni] - Y[i];
double d = sqrt(dx * dx + dy * dy);
chmin(dp[ni][ns], dp[i][j] + d);
}
}
}
vector<double> cand = dp[N - 1];
rep2(i, 1, C) {
cand[i] += (double)(1ll << (i - 1));
}
double ans = *min_element(all(cand));
printf("%.9lf\n", ans);
}
G. Ai + Bj + Ck = X (1 <= i, j, k <= N)
https://atcoder.jp/contests/abc315/tasks/abc315_g