std拿py写的(因为这是我以前的py项目,反正是spj),是高斯消元+状态压缩的题,结果T飞,本蒟蒻又不会改c++,求大佬指导QwQ
py版std:
from math import ceil
from typing import List, Tuple
# 定义各种类型标
SolveType = List[Tuple[int, int]]
BoardType = List[List[int]]
EquationType = List[Tuple[List[Tuple[int, int]], Tuple[int, int]]]
WIDTH = 8 # 格数
WHITE, BLACK = 0, 1
def get_blank_board(): # 获取一个空白盘面
return [[WHITE] * WIDTH for _ in range(WIDTH)]
def get_periphery(x: int, y: int): # 求所有周边点,包括自己
res = [(x, y)]
for tx, ty in ((0, 1), (1, 0), (0, -1), (-1, 0)):
nx, ny = x + tx, y + ty
if 0 <= nx < WIDTH and 0 <= ny < WIDTH:
res.append((nx, ny))
return res
def equation(): # 列异或方程组
res = []
for x in range(WIDTH):
for y in range(WIDTH):
periphery = get_periphery(x, y)
res.append((periphery, (x, y)))
return res
def chunk(x: list, step: int): # 按步长切割列表x
step = int(step)
return list(
map(
lambda n: x[n * step: n * step + step],
list(range(0, ceil(len(x) / step)))
)
)
def gaussian(equ: EquationType): # 异或方程组转矩阵
matrix = [] # 增广矩阵
# 系数1 系数2 ... 系数64 等号右侧
for xs, pos in equ:
p = []
for x, y in xs:
p.append(x * WIDTH + y)
a = [0] * (WIDTH * WIDTH)
for i in p:
a[i] = 1 # 系数只有1或0
a.append(array_to_int([pos])) # 右端常数
matrix.append(a)
return matrix
def array_to_int(array: SolveType): # 解法转十进制整数
board = get_blank_board()
for x, y in array:
board[x][y] = BLACK
flatten = lambda x: [y for L in x for y in flatten(L)] if type(x) is list else [x] # 碾平二维列表
a = flatten(board)
del flatten
res = [0] * (WIDTH * WIDTH)
for inx, item in enumerate(a):
if item == BLACK:
res[inx] = 1
res = ''.join(str(i) for i in res) # 矩阵转二进制
return int(res, base=2) # 二进制转整数
def int_to_array(n: int): # 十进制整数转解法
lst = list(bin(n).replace('0b', ''))
lst = ['0'] * (WIDTH * WIDTH - len(lst)) + lst # 补0
board = [0] * (WIDTH * WIDTH)
for inx, item in enumerate(lst):
if item == '1':
board[inx] = BLACK
board = chunk(board, WIDTH)
return board
def guass(n: int, matrix: BoardType): # 高斯消元法解异或方程组
r = 0
for c in range(n):
t = r
for i in range(r, n): # 找1
if matrix[i][c] == 1:
t = i
break
if matrix[t][c] == 0:
continue
matrix[r], matrix[t] = matrix[t], matrix[r] # 交换两行
for i in range(r + 1, n): # 1与r行异或
if matrix[i][c] == 1:
for j in range(c, n + 1):
matrix[i][j] ^= matrix[r][j] # 合并
r += 1
for i in range(n - 1, -1, -1): # 注意是倒序
for j in range(i):
if matrix[j][i] == 1:
matrix[j][n] ^= matrix[i][n]
for i in range(n):
yield matrix[i][n]
def solve(): # 获取解方程的结果
m = gaussian(equation())
res = {} # 哈希表存储
for inx, num in enumerate(guass(WIDTH * WIDTH, m)):
val = int_to_array(num)
x, y = inx // WIDTH, inx % WIDTH # 一维转二维公式
res[(x, y)] = val
return res
def merge(a: BoardType, b: BoardType): # 合并两组解,实际上就是异或
if not a:
return b
if not b:
return a
res = get_blank_board()
for x, i in enumerate(a):
for y, j in enumerate(i):
k = b[x][y]
if k == j: # 异或核心
res[x][y] = WHITE
else:
res[x][y] = BLACK
return res
def get(board: BoardType): # 主函数
solution = solve()
res = []
for x, i in enumerate(board):
for y, j in enumerate(i):
if j == BLACK:
res.append(solution[(x, y)])
ans = []
for i in res:
ans = merge(ans, i) # 合并解法,减少空间和可视化消耗
res = []
for x, i in enumerate(ans):
for y, j in enumerate(i):
if ans[x][y] == BLACK:
res.append((x, y))
return res
n = WIDTH = int(input())
a = get_blank_board()
for i in range(n):
a[i] = list(map(int, input().split()))
res = get(a)
print(len(res))
for x, y in res:
print(x + 1, y + 1)