寒假思维训练计划day14 A. The Very Beautiful Blanket

寒假思维训练计划day14

今天做了一道很妙的矩阵构造题, 很有收获,而且是有关于异或运算的。题目链接,有需自取:Problem - A - Codeforces


摘要:

part1 题意

part2 题解 (有数学推导和矩阵举例)

part3 代码(python代码) 


Part1 题意:Problem - A - Codeforces

题意:

给定n和m(4 <= n, m <= 200),要求构造一个矩阵满足每个4 * 4的矩阵,满足左上角2 * 2的矩阵所有值的异或等于右下角,右上角的所有值的异或等于左下角,元素的值必须满足小于2^{63}且大于等于0 ,先输出最大的不同元素的个数,再输出矩阵。


Part2 题解:

题解:

以后遇到矩阵构造,可以多往递推、打表、循环构造思考。

1、我们先来看一下异或有什么性质(下面会用到):

性质1:奇数\oplus奇数 = 偶数
性质2:奇数\oplus偶数 = 奇数 

性质3:偶数\oplus偶数 = 偶数  

性质4:满足交换律和结合律

2、对于任意一个2 * 2的矩阵:\begin{bmatrix} a & b\\ c & d \end{bmatrix},先这样构造\begin{bmatrix} 1 & 0& 1& 0& 1 \\ 0 & 0 & 0 & 0 & 0 \\ 1 & 0& 1& 0& 1\\ 0& 0 & 0 &0 & 0 \end{bmatrix},其中1为奇数,0为偶数,我们构造任意一个2 * 2的矩阵都是偶数异或奇数,此时要使所有的2 * 2矩阵满足异或值为1,我们先确定最开始的2 * 2矩阵:a[1][1] = 2 \oplus 4 \oplus 8 \oplus 1,a[1][2] = 2, a[2][1] = 4, a[2][2] = 8, 即 \begin{bmatrix} 1 & 2\\ 4 & 8 \end{bmatrix},现在我们继续观察让相邻矩阵怎么样能等价这样可以实现递推,假设两个相邻的矩阵\begin{bmatrix} a &c\\ b & d \end{bmatrix} \begin{bmatrix} c & e\\ d & f \end{bmatrix}

a \oplus b \oplus (c \oplus d) = e \oplus f \oplus (c \oplus d), 此时对于c和d,我们同时加一个不存在a,b当中的一个二进制位假设是2^j, 这样子c和d就能抵消掉这个二进制位实现,假设再往后我们再加同一个二进制位可以实现吗,我们可以看看矩阵的递推变化:\begin{bmatrix} a & c& a + 2^j& c + 2^j & a + 2^{j + 1}\\ b& d& b + 2^j & d + 2^j& b + 2^{j + 1} \end{bmatrix} <=> \begin{bmatrix} a & c\\ b & d \end{bmatrix} \rightarrow \begin{bmatrix} c & a + 2^j\\ d & b + 2^j \end{bmatrix} \rightarrow \begin{bmatrix} a + 2^j & c + 2^j\\ b + 2^j & d + 2^j \end{bmatrix} \rightarrow \begin{bmatrix} c + 2^j & a + 2^{j + 1}\\ d + 2^j & b + 2^{j + 1} \end{bmatrix}\rightarrow ....
假设我们把值按这样的方式递推:F[i] = F[i - 2] + 2^j, 我们发现随着递推进行,每个2 * 2矩阵好像都满足异或值为1,最后我们先用2^j把第1、2行确定,再从第3行这样用2^{k}递推,最终一定满足每个矩阵的异或是1,
因为第一二行是统一从左往右递推,第三行到第n行是从上往下递推,对于第一、二一定是
满足上下元素拥有增加的二进制位可以抵消,对于第二行开始往下看,一定有两个左右元素用有\sum 2^k,也能相消,所以拥有这种性质,可以构造每个2 * 2矩阵异或值等于任何数,只要能找到满足不冲突的j, k
也就是(这是一个例矩阵):
\begin{bmatrix} 1 & 2 & 1 + 2^j& 2 + 2^j & 1 + 2^j + 2^j\\ 4 & 8 & 4 + 2^j& 8 + 2^j& 4 + 2^j + 2^j\\ 1 + 2^k & 2 + 2^k & 1 + 2^j + 2^k& 2 + 2^j + 2^k& 1 + 2^j + 2^j + 2^k\\ 4 + 2^j& 4 + 2^k & 4 + 2^j + 2^k & 8 + 2^j + 2^k & 4 + 2^j + 2^j + 2^k\\ \end{bmatrix}


Part3 代码(python代码):

import math 
T = int(input()) 
n, m = 0, 0 
while T != 0:
    n, m = map(int, input().strip().split(' '))
    us = [[0] * (m + 2) for i in range(n + 2)]        
    c = 0 
    #先构造第一个2 * 2的矩阵
    us[1][1] = 2 ^ 4 ^ 6 ^ 1
    us[1][2] = 2 
    us[2][1] = 4
    us[2][2] = 8 
    # 构造第一二行是从左往右递推的。
    for i in range(3, m + 1, 2):
        us[1][i] = us[1][i - 2] + (1 << 5) 
        us[1][i + 1] = us[1][i - 1] + (1 << 5) 
        us[2][i] = us[2][i - 2] + (1 << 5) 
        us[2][i + 1] = us[2][i - 1] + (1 << 5) 
    # 构造第三行开始从上往下递推。
    for i in range(3, n + 1):
        for j in range(1, m + 1):
            us[i][j] = us[i - 2][j] + (1 << 16) 
    print(n * m) 
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            print(us[i][j], end = ' ') 
        print()
    T -= 1 

你可能感兴趣的:(算法,python,c++)