倉庫の電灯を全部点けるスイッチ

  • 全探索
  • 問題 11
  • ふつう
  • 目安 31 分

押すたびに決まった電灯の点灯と消灯を入れ替えるスイッチが並ぶ。押す順番は結果に関係ないことに気づき、押すか押さないかの全通りをビットで調べて、最も少ない押す回数を答える練習です。

本番の試験は PC で受けることが多いので、PC での練習をすすめます。スマホでも、読んで、書いて、採点するところまで動きます。

入力は標準入力から読み、答えは標準出力に書きます。1 テストあたり 2 秒までです。

問題

倉庫に 1 から M までの番号の付いた M 個の電灯と、1 から N までの番号の付いた N 個のスイッチがあります。スイッチ i を 1 回押すと、決まった k_i 個の電灯のそれぞれについて、点いていれば消え、消えていれば点きます。ほかの電灯は変わりません。

いまの電灯の状態が与えられます。スイッチを何回か押して、M 個の電灯を全部点いた状態にしたいです。同じスイッチを何回押してもかまいません。全部を点けるのに必要な、スイッチを押す回数の合計の最小を出力してください。最初から全部点いていれば 0 です。どう押しても全部を点けられないときは -1 を出力してください。

入力の形式

N M
S
k_1 c_1,1 c_1,2 ... c_1,k_1
k_2 c_2,1 c_2,2 ... c_2,k_2
...
k_N c_N,1 c_N,2 ... c_N,k_N

1 行目にスイッチの数 N と電灯の数 M が並びます。2 行目の S は 0 と 1 だけの M 文字の文字列で、左から j 文字目が 1 なら電灯 j はいま点いていて、0 なら消えています。3 行目から N 行は、i 行目がスイッチ i の説明です。先頭の k_i が入れ替える電灯の数で、続く k_i 個がその電灯の番号です。

出力の形式

押す回数の合計の最小 (全部を点けられないときは -1) を 1 行に出力します。

制約

  • N は 1 以上 16 以下です
  • M は 1 以上 20 以下です
  • S は 0 と 1 だけからなる長さ M の文字列です
  • k_i は 1 以上 M 以下です
  • 電灯の番号 c_i,1 から c_i,k_i は 1 以上 M 以下で、小さい順に並び、同じ番号はありません

入力と出力の例

例 1

電灯 1 と 3 が点いていて、2 と 4 が消えています。スイッチ 1 (電灯 1 と 2) とスイッチ 2 (電灯 1 と 4) を 1 回ずつ押すと、電灯 1 は 2 回入れ替わって点いたまま、2 と 4 が点き、全部が点きます。1 回だけで全部を点けるスイッチは無いので、答えは 2 です。

入力

3 4
1010
2 1 2
2 1 4
2 3 4

出力

2

例 2

スイッチ 1 もスイッチ 2 も電灯 1 と 2 をいっしょに入れ替えるので、電灯 1 だけ消えた状態から、電灯 1 だけを点けることはできません。

入力

2 2
01
2 1 2
2 1 2

出力

-1

例 3

最初から全部点いているときは、押さなくてよいので 0 です。

入力

1 3
111
1 2

出力

0

ヒント

まだ開いていません

付箋は 3 枚。下の段ほど答えに近づきます

  1. ヒント 2

  2. ヒント 3答えに近い

main.py
import sys

data = sys.stdin.read().split()
n, m = int(data[0]), int(data[1])
state = data[2]
switches = []
pos = 3
for i in range(n):
    k = int(data[pos])
    switches.append([int(c) for c in data[pos + 1:pos + 1 + k]])
    pos += 1 + k

# ここから書く

入力

出力

「実行する」を押すと、ここに出力が出ます

できているか「提出して採点」を押すと、隠れたテストを全部走らせて、通ったかをここに出します