ABC 424
Table of Contents
https://atcoder.jp/contests/abc424
A. Isosceles
https://atcoder.jp/contests/abc424/tasks/abc424_a
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
vint v(3);
rep(i, 3) cin >> v[i];
sort(all(v));
yesno(v[0] == v[1] || v[1] == v[2]);
}
B. Perfect
https://atcoder.jp/contests/abc424/tasks/abc424_b
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N, M, K;
cin >> N >> M >> K;
vint A(K), B(K);
rep(i, K) {
cin >> A[i] >> B[i];
A[i]--, B[i]--;
}
vvint sol(N, vint(M));
vint ans;
rep(i, K) {
sol[A[i]][B[i]] = 1;
int cnt = 0;
rep(j, M) if (sol[A[i]][j]) cnt++;
if (cnt == M) ans.push_back(A[i] + 1);
}
print(ans);
}
C. New Skill Acquired
https://atcoder.jp/contests/abc424/tasks/abc424_c
自力 AC. コンテスト後にグラフに落とし込めるとわかったが、コンテスト中は stack 使って実質再帰の処理を書いた。
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N;
cin >> N;
vint start;
vvint graph(N + 1);
rep(i, N) {
ll a, b;
cin >> a >> b;
if (a == 0 && b == 0) {
graph[0].push_back(i + 1);
} else {
graph[a].push_back(i + 1);
graph[b].push_back(i + 1);
}
}
vint visited(N + 1);
auto dfs = [&](auto dfs, int x) -> void {
for (auto nx : graph[x]) {
if (visited[nx]) continue;
visited[nx] = 1;
dfs(dfs, nx);
}
};
dfs(dfs, 0);
ll ans = accumulate(all(visited), 0ll);
cout << ans << endl;
}
D. 2x2 Erasing 2
https://atcoder.jp/contests/abc424/tasks/abc424_d
解説 AC.
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int M = 7;
// 連続する行の中に 2x2 の黒いマスが存在しないか判定
auto judge = [&](int a, int b) -> bool {
int t = a & b;
rep(i, M - 1) {
if (t >> i & 1 && t >> (i + 1) & 1) return false;
}
return true;
};
auto cal = [&]() -> void {
ll H, W;
cin >> H >> W;
vector<string> tmpgrid(H);
rep(i, H) cin >> tmpgrid[i];
vint grid(M + 1);
rep(i, H) rep(j, W) {
if (tmpgrid[i][j] == '#') {
grid[i + 1] ^= 1 << j;
}
}
// sentinel として 0 行目を全て白いマスとして追加
// dp[i][state] := i 行目まで見たときに i 行目の状態が state で、また 0 ~ i 行目までに2x2の黒マスが存在しないように白マスで塗りつぶすときの最小値
vvll dp(M + 1, vll(1 << M, INF));
dp[0][0] = 0;
rep2(i, 1, M + 1) rep(pr, 1 << M) rep(nx, 1 << M) {
if (!judge(pr, nx)) continue;
// i 行目を nx の状態にできるか判定
// できるのであれば何個のマスを白マスにする必要があるか数える
ll cnt = 0;
int row = grid[i];
int ok = 1;
rep(j, M) {
int l = (row >> j & 1);
int r = (nx >> j & 1);
if (l == 0 && r == 1) {
ok = 0;
break;
}
if (l == 1 && r == 0) cnt++;
}
if (!ok) cnt = INF;
chmin(dp[i][nx], dp[i - 1][pr] + cnt);
}
ll ans = INF;
rep(st, 1 << M) chmin(ans, dp[M][st]);
cout << ans << '\n';
};
int t;
cin >> t;
rep(i, t) cal();
}
E. Cut in Half
https://atcoder.jp/contests/abc424/tasks/abc424_e
F. Adding Chords
https://atcoder.jp/contests/abc424/tasks/abc424_f