3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ABC412 備忘録

Last updated at Posted at 2025-06-28

今回はPythonでABC412をABDを解くことができたので、備忘録を纏めました。

コンテスト概要

日本最強プログラマー学生選手権~Advance~ -予選- (AtCoder Beginner Contest 412)

開催日:2025年6月28日 21:00-22:40


A - Task Failed Successfully

方針

N日間の間の中でABを比べてBの方が大きかった場合をカウントするだけの問題。

N = int(input())
ans = 0
for i in range(N):
    a, b = map(int,input().split())
    if a < b:
        ans += 1
print(ans)

B - Precondition

方針

文字列Sにおいて、先頭以外の位置(2文字目以降)にある英大文字について、
その直前の文字(S[i - 1])が 文字列Tに含まれていない場合は不適。

S[i] が英大文字かどうかを isupper() で判定。
かつ、直前の文字S[i - 1]Tに含まれていなければ、Noと返す。

S = input().strip()
T = input().strip()

ok = True
for i in range(1, len(S)):
    if S[i].isupper() and S[i - 1] not in T:
        ok = False
        break

print("Yes" if ok else "No")

D - Make 2-Regular Graph

項目 内容
目標 全ての頂点の次数が2のグラフにするための最小操作数を求める
方法 全てのN本の辺の組み合わせから「次数2」のものを列挙し、差分をとって操作数を最小化
ポイント グラフ構造、次数チェック、全探索、集合演算

方針

  • 頂点数Nが最大8までなので、「すべての可能なグラフ構造を試す」(=全探索)が可能
  • 重要なのは、「N個の辺でできた、すべての頂点の次数が2のグラフ(=サイクル構成)」だけを調べること
  • その中で、現在のグラフとどれくらい違うか(追加や削除が必要か)を調べて最小回数を更新

サイクルグラフかどうかの判定

頂点の次数を数えて、すべて2かをチェック

  • 与えられた辺集合 edge_set に対して、各頂点に何本の辺がつながっているか(=次数)を数える
  • すべての頂点の次数が 2本ちょうど ならば OK(=理想の状態)
def is_valid_cycle_graph(edge_set):
    degree = [0] * N
    for a, b in edge_set:
        degree[a] += 1
        degree[b] += 1
    return all(d == 2 for d in degree)

全ての可能な辺の組み合わせを試す

  • 0 〜 N − 1のすべての可能な辺を列挙
  • (i, j)としてi < jを守ることで、無向グラフの重複を防ぐ
all_possible_edges = [(i, j) for i in range(N) for j in range(i + 1, N)]

全てのN本の辺の組み合わせを試す

  • combinations(all_possible_edges, N) は、N本の辺を選ぶすべての組み合わせ
  • 「次数が2のグラフ」は必ず辺の本数がN本になる
min_ops = float('inf')  # 最小操作回数を無限大で初期化

for edge_subset in combinations(all_possible_edges, N):

差分のコスト計算

to_add = edge_set - edges
to_remove = edges - edge_set
ops = len(to_add) + len(to_remove)

現在の候補 edge_set を実現するには:

  • edges にない辺:追加
  • edge_set にない現在の辺:削除

最後に最小値の更新を行う。

全体

from itertools import combinations
import sys

input = sys.stdin.read
data = input().split()

N = int(data[0])
M = int(data[1])
edges = set()

for i in range(M):
    a = int(data[2 + 2 * i]) - 1
    b = int(data[3 + 2 * i]) - 1
    edges.add((min(a, b), max(a, b)))

from itertools import permutations

def is_valid_cycle_graph(edge_set):
    degree = [0] * N
    for a, b in edge_set:
        degree[a] += 1
        degree[b] += 1
    return all(d == 2 for d in degree)

all_possible_edges = [(i, j) for i in range(N) for j in range(i + 1, N)]

min_ops = float('inf')

# 全ての辺集合の中から、サイズがNのサブセット(次数2で全頂点カバーする可能性がある)を列挙
for edge_subset in combinations(all_possible_edges, N):
    edge_set = set(edge_subset)
    if is_valid_cycle_graph(edge_set):
        # 差分を計算(追加 + 削除の最小コスト)
        to_add = edge_set - edges
        to_remove = edges - edge_set
        ops = len(to_add) + len(to_remove)
        min_ops = min(min_ops, ops)

print(min_ops)

結果

ABD 3完
順位 2273th / 11564
パフォーマンス 1144
レーティング 238 → 473 (+235)

感想

今回のコンテストで運よく入茶することができました。
D問題に関しては、制約が緩かったため解けたのでラッキーでした。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?