# ABC189 D - Logical Expression
ABC189 D - Logical Expression
問題へのリンク
問題概要
AND または OR である。
値が True または False であるような True となるようなものの個数を求めよ。
y_0 = x_0 -
のとき、i \geq 1 がS_i ANDなら 、y_i = y_{i - 1} \land x_i がS_i ORならy_i = y_{i - 1} \lor x_i
制約
AND または OR
ABC中の解答
要は True と False が並ぶ間に論理積と論理和がずらずらと並んで最終的に True ってなるのは何個ありますか?という問題。
まずはノートでちょこちょこ考えてみた。論理積と論理和は順番を入れ替えてもいい(この理論そもそも間違い?)ので、論理積を左側に論理和を右側に固めると結局論理積の塊は一個でも False だとダメで、一方論理和は一個でも True ならOKと言える。最後、論理積と論理和の塊を OR でまとめると(これ多分 AND でまとめたほうが楽)
論理積の塊 False False
のとき False になる。よって全体の組み合わせ
制約が
論理積が A 個ある時、全体が False になる組み合わせ:
論理和が B 個ある時、全体が False になる組み合わせ:1 (全部 False のときだけ)
よって求める計算式は
以下のように実装しsampleではACとなったものの提出したらWAとなってしまった。
どこかの理論に穴があったようで、固執してあれこれ考えたけどタイムアップ。
from collections import Counter
N = int(input())
S = Counter([input() for _ in range(N)])
if len(S) == 1:
key = list(S.keys())[0]
if key == 'AND':
print(1)
else:
print(2**(N + 1) - 1)
exit()
v1 = 2**(S['AND'] + 1) - 1
v2 = 2**S['OR'] - 1
ans = 2**(N + 1) - v1 * v2
print(ans)
公式解法1
たまにある解き方の 後ろから考えていくパターン の問題であった。
-
S_N = 'AND'のとき、 がy_N Trueになるためには とy_{N-1} は必ずx_N Trueである必要がある。 -
S_N = 'OR'のとき、 がy_N Trueになるためには がx_N Trueなら はなんでもよく、y_{N-1} Falseなら はy_{N-1} Trueでなければならない。
このルールで後ろから順に一つずつ
一度こうだと考えてハマったときに別解法を考えるきっかけってみんなどうしているんだろうか?
N = int(input())
S = [input() for _ in range(N)]
ans = 1
for i, s in enumerate(S[::-1]):
if s == 'OR':
ans += 2**(N - i)
print(ans)
Discussion