AtCoder上にある問題のうち、AtCoder Problemsでdiff 800以上と判定されているものを順番に解いていく企画。
基本的な考え方は全てコード中のコメントに入れてあるので、参照のこと。
出典:
AtCoder Beginner Contest 128 C – Switches
競技プログラミングに慣れてない人だと、あっちを立てればこっちが立たず……と、どう考えたらいいのか頭を抱える系の問題だと思う。が、要するに全探索でいい。1000通り程度を全部試すなど、文字通り一瞬だ。
ただ、全探索といってもどのように書くか、というのがあるわけで、今回のような問題では、bit全探索と呼ばれる手法を使うと書きやすい。
下のコードだけではどうも良くわからない……という人向けに、そもそもビット列・ビット演算とは何かというところから説明した文書(Jupyter Notebook)も作成してみたので、よければ参考にどうぞ。
brute_force_with_bitmask.ipynb
def main():
N, M = map(int, input().split())
lamp_dat = [list(map(int, input().split()))[1:] for _ in range(M)]
switches = [[] for _ in range(N)]
for i, sw_list in enumerate(lamp_dat):
for sw in sw_list[1:]:
switches[sw-1].append(i)
lit_cond = int(''.join(input()[::-1].split()), 2)
result = 0
for st in range(1<<N):
lamp_status = 0
for i in range(N):
if st>>i & 1:
for lmp in switches[i]:
lamp_status = lamp_status ^ (1<<lmp)
if lamp_status == lit_cond:
result += 1
print(result)
main()
関連