結果
| 問題 |
No.1954 CHECKER×CHECKER(2)
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-03-20 20:20:27 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 68 ms / 1,000 ms |
| コード長 | 6,369 bytes |
| コンパイル時間 | 150 ms |
| コンパイル使用メモリ | 82,348 KB |
| 実行使用メモリ | 72,432 KB |
| 最終ジャッジ日時 | 2025-03-20 20:21:17 |
| 合計ジャッジ時間 | 2,530 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 29 |
ソースコード
def main():
import sys
input = sys.stdin.read().split()
idx = 0
H = int(input[idx]); idx +=1
W = int(input[idx]); idx +=1
S = []
for _ in range(H):
s = input[idx].strip(); idx +=1
row = [1 if c == '#' else 0 for c in s]
S.append(row)
M = int(input[idx]); idx +=1
type1 = [] # list of n_i for type1 operations
type2 = [] # list of n_i for type2 operations
seen1 = set()
seen2 = set()
for _ in range(M):
t = int(input[idx]); idx +=1
n = int(input[idx]); idx +=1
if t == 1:
if n not in seen1:
type1.append(n)
seen1.add(n)
else:
if n not in seen2:
type2.append(n)
seen2.add(n)
type1 = sorted(type1)
type2 = sorted(type2)
def check_pattern(target_generator):
# Generate c matrix
c = [[0]* (W+1) for _ in range(H+1)] # 1-based
for i in range(1, H+1):
for j in range(1, W+1):
target = target_generator(i, j)
s_val = S[i-1][j-1]
c[i][j] = target ^ s_val
# Check row consistency
base_row = 1
row_diff = [0]*(H+1)
for i in range(1, H+1):
row_diff[i] = c[i][1] ^ c[base_row][1]
for j in range(1, W+1):
expected = c[base_row][j] ^ row_diff[i]
if c[i][j] != expected:
return None
# Check column consistency
base_col = 1
col_diff = [0]*(W+1)
for j in range(1, W+1):
col_diff[j] = c[base_row][j] ^ c[base_row][base_col]
for i in range(1, H+1):
expected = c[i][base_col] ^ col_diff[j]
if c[i][j] != expected:
return None
# Construct two possible solutions
solutions = []
# Solution 1: rows1[1] =0
rows1 = [0]*(H+1)
cols1 = [0]*(W+1)
for i in range(1, H+1):
rows1[i] = row_diff[i]
for j in range(1, W+1):
cols1[j] = c[base_row][j]
solutions.append((rows1, cols1))
# Solution 2: rows2[1] =1
rows2 = [0]*(H+1)
cols2 = [0]*(W+1)
for i in range(1, H+1):
rows2[i] = row_diff[i] ^ 1 # row_diff[i] is c[i][1]^c[1][1], so rows[1] =1→1^0 → row_diff[i]^1
for j in range(1, W+1):
cols2[j] = c[base_row][j] ^1
solutions.append((rows2, cols2))
return solutions
# Check two possible checkerboard patterns
# Pattern 1: (i+j) %2 ==0
def target1(i, j):
return (i + j) % 2
solutions1 = check_pattern(target1)
# Pattern 2: (i+j+1) %2 ==0
def target2(i, j):
return (i + j +1) %2
solutions2 = check_pattern(target2)
# Now, check if any solution can be formed by the operations
def can_form(target, type_list, max_dim):
# target is a list [1..max_dim], 1-based.
# type_list is list of n_i operations.
# max_dim is H or W.
# Check if the target can be represented as the XOR of some operations in type_list.
# Operations are (1-based)n_i: prefix.
# Gauss elimination for binary vectors (mod 2)
basis = {}
# Sort operations in decreasing order
sorted_ops = sorted(type_list, reverse=True)
for n in sorted_ops:
vec = [0]*(max_dim +1)
for r in range(1, n+1):
vec[r] = 1
# Reduce this vector
current = vec.copy()
pivot = -1
for r in range(max_dim, 0, -1):
if current[r] ==1:
pivot = r
break
if pivot == -1:
continue # zero vector, skip
if pivot not in basis:
basis[pivot] = current
else:
# XOR with basis[pivot]
for r in range(1, pivot+1):
current[r] ^= basis[pivot][r]
# Find new pivot
new_pivot = -1
for r in range(pivot-1, 0, -1):
if current[r] ==1:
new_pivot = r
break
if new_pivot == -1:
continue # no new pivot
else:
# Check if this new_pivot is in basis
while new_pivot in basis:
# XOR with basis[new_pivot]
for r in range(1, new_pivot+1):
current[r] ^= basis[new_pivot][r]
# Find next pivot
new_pivot = -1
for r in range(new_pivot-1, 0, -1):
if current[r] ==1:
new_pivot = r
break
if new_pivot == -1:
break
if new_pivot != -1:
basis[new_pivot] = current.copy()
# Now, check if target can be formed
current = [0]*(max_dim+1)
for r in range(1, max_dim+1):
current[r] = target[r]
# Apply basis vectors in reverse order
for pivot in sorted(basis.keys(), reverse=True):
if current[pivot]:
# XOR with basis[pivot]
for r in range(1, pivot+1):
current[r] ^= basis[pivot][r]
# Check if all zero
return sum(current[1:max_dim+1]) ==0
found = False
for solutions in [solutions1, solutions2]:
if not solutions:
continue
for rows, cols in solutions:
# Check rows via type1 operations
target_rows = [0]*(H+1)
for r in range(1, H+1):
target_rows[r] = rows[r]
ok_rows = can_form(target_rows, type1, H)
if not ok_rows:
continue
# Check cols via type2 operations
target_cols = [0]*(W+1)
for c in range(1, W+1):
target_cols[c] = cols[c]
ok_cols = can_form(target_cols, type2, W)
if ok_cols:
found = True
break
if found:
break
print("Yes" if found else "No")
if __name__ == "__main__":
main()
lam6er