我正在为下一个谜语寻找有效的解决方案:
对数据结构没有限制。
我在javascript中的幼稚解决方案:
const next = (bit, matrix) => {
matrix.shift()
matrix.push(bit);
const matrix_size = Math.sqrt(matrix.length);
let col_sum = 0;
let row_sum = 0;
for (let i = 0; i < matrix.length; ++i) {
col_sum = matrix[i];
row_sum += matrix[i];
if ((i + 1) % matrix_size === 0) {
if (row_sum === matrix_size) return true;
row_sum = 0;
}
for (let j = i + matrix_size;j < (i + ((matrix_size * matrix_size) - 1)); j += matrix_size) {
col_sum += matrix[j];
}
if (col_sum === matrix_size) return true;
}
return false;
}
我使用1d数组作为数据结构,但实际上并不能帮助我减少时间复杂度。
喜欢听到一些想法:)
答案 0 :(得分:3)
让我们考虑以下示例矩阵:
[0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 1, 1,
1, 1, 1, 1]
并推零16次。
然后,将获得False,True,True,True,False,True,True,True,False,True,True,True,False,False False和False。
存在循环行为(False,True,True,True)。
如果连续的长度是固定的,则不必每次更新都重新计算。
更新矩阵后,可以更改左上角和右下角连续字符的长度,并且可能需要更新循环存储器。
维持连续的序列,保持受序列影响的循环行为总数,行的复杂度将在O(1)
中。
在使用列的情况下,让matrix[cur]=bit
和cur = (cur+1)%(matrix_size*matrix_size)
代替cur
来表示O(1)
作为矩阵的实际左上角。
维持每一列的col_sum,维持满足全条件的总数,复杂度将为class Matrix:
def __init__(self, n):
self.mat = [0] * (n*n)
self.seq_len = [0] * (n*n)
self.col_total = [0] * n
self.col_archive = 0
self.row_cycle_cnt = [0] * n
self.cur = 0
self.continued_one = 0
self.n = n
def update(self, bit):
prev_bit = self.mat[self.cur]
self.mat[self.cur] = bit
# update col total
col = self.cur % self.n
if self.col_total[col] == self.n:
self.col_archive -= 1
self.col_total[col] += bit - prev_bit
if self.col_total[col] == self.n:
self.col_archive += 1
# update row index
# process shift out
if prev_bit == 1:
prev_len = self.seq_len[self.cur]
if prev_len > 1:
self.seq_len[(self.cur + 1) % (self.n * self.n)] = prev_len-1
if self.n <= prev_len and prev_len < self.n*2:
self.row_cycle_cnt[self.cur % self.n] -= 1
# process new bit
if bit == 0:
self.continued_one = 0
else:
self.continued_one = min(self.continued_one + 1, self.n*self.n)
# write the length of continued_one at the head of sequence
self.seq_len[self.cur+1 - self.continued_one] = self.continued_one
if self.n <= self.continued_one and self.continued_one < self.n*2:
self.row_cycle_cnt[(self.cur+1) % self.n] += 1
# update cursor
self.cur = (self.cur + 1) % (self.n * self.n)
return (self.col_archive > 0) or (self.row_cycle_cnt[self.cur % self.n] > 0)
def check2(self):
for y in range(self.n):
cnt = 0
for x in range(self.n):
cnt += self.mat[(self.cur + y*self.n + x) % (self.n*self.n)]
if cnt == self.n:
return True
for x in range(self.n):
cnt = 0
for y in range(self.n):
cnt += self.mat[(self.cur + y*self.n + x) % (self.n*self.n)]
if cnt == self.n:
return True
return False
if __name__ == "__main__":
import random
random.seed(123)
m = Matrix(4)
for i in range(100000):
ans1 = m.update(random.randint(0, 1))
ans2 = m.check2()
assert(ans1 == ans2)
print("epoch:{} mat={} ans={}".format(i, m.mat[m.cur:] + m.mat[:m.cur], ans1))
。
pyinstaller