Please sign in first.
Official
A - Flip Row or Col 2 Editorial
by
A - Flip Row or Col 2 Editorial
by
toam
\(M=\lfloor \frac{N-1}{4}\rfloor\) とします.
まず,\(1\) 行目がすべて \(0\) になるように適宜列 flip をしておきます.\(1\) 行目がすべて \(0\) である状態から列 flip できる箇所はちょうど \(R_1(\leq M)\) 個です.
各行について見ていきます.もし行に含まれる \(1\) の個数が \(N/2\) 以上だった場合,\(1\) の個数は列 flip によって最大でも \(M\) 個しか減らないため,行の総和を \(R_i\) にすることはできません(\(R_i\leq M\lt N/2-M\) であるため).したがって,行の総和が \(N/2\) 以上である場合はその行を flip してよいです.すべての行に対してこの処理が終わったら,これ以降で 行 flip する必要はありません.
次は各列について見ていきます.行 flip は行わないため,列 \(j\) の総和は \(C_j\) または \(N-C_j\) である必要があります.\(N-C_j\) のときは列 \(j\) を flip します.
これらの操作によって得られた \(A\) が各行の総和の条件を満たしているか判定すればよいです.
以上をまとめると,
- \(1\) 行目が全部 \(0\) になるように列 flip をする.
- 各行に対して,総和が \(N/2\) 以上であればその行を flip する.
- 各列に対して,総和が \(N/2\) 以上であればその列を flip する.
- 得られた行列が条件を満たすか判定する.
という手順でこの問題を解くことができます.計算量は \(O(N^2)\) です.
def solve():
N = int(input())
A = [[int(j) for j in input()] for i in range(N)]
R = list(map(int, input().split()))
C = list(map(int, input().split()))
op_row = [0] * N
op_col = [0] * N
def flip_row(i):
op_row[i] ^= 1
for j in range(N):
A[i][j] ^= 1
def flip_col(j):
op_col[j] ^= 1
for i in range(N):
A[i][j] ^= 1
for j in range(N):
if A[0][j] == 1:
flip_col(j)
for i in range(N):
if sum(A[i]) >= (N + 1) // 2:
flip_row(i)
for j in range(N):
if sum(A[i][j] for i in range(N)) >= (N + 1) // 2:
flip_col(j)
for i in range(N):
if sum(A[i]) != R[i]:
return print("No")
for j in range(N):
if sum(A[i][j] for i in range(N)) != C[j]:
return print("No")
print("Yes")
print(*op_row, sep="")
print(*op_col, sep="")
T = int(input())
for _ in range(T):
solve()
posted:
last update:
