题意
给你一个m(m\in \lbrace 2^k | k=1,2,...,10\rbrace),你需要构造一个m\times m的矩阵,要求任意两行的内积为0,内积也叫点积:对于a,b有a\cdot b=\sum _{i=1}^{n}a_ib_i=a_1b_1+a_2b_2+\cdots +a_nb_n
思路
构造,当n=2的时候,我们构造出

嗯,然后按照下面方法构造,我问大佬们为什么,感觉是对的,他们说“瞎**构造”就好
就是每个这样的小块往其他方向填:

每次递归,有一个v,要么是1,要么是-1,然后往其他地方填

然后这个时候,相当于又是矩阵的开始,这回是4个4\times 4小矩阵,然后继续往下dfs

然后继续往下传递,继续分成若干个2\times 2的矩阵,直到n=1的时候填入当前的v
如何理解v?
这个v就是我们之后要填入数字的数,但是会一直变化,比如-1\times (-1)=1,这个时候又是1了,
正如上图右下角,这整块的v 是-1
,但是会随着之后的变化可能会改变,比如最后一个变成了1
如何理解可行性?
我的理解是整体都满足,一开始从小的2\times 2的矩阵慢慢变大,同样满足,实际上我们能看出,大的矩阵的v进行内积计算还是0,所以一直满足
代码
inline void dfs(int i,int j,int n,int v)
{
if (n==1) {a[i][j]=v;return;}
dfs(i,j,n/2,v);
dfs(i+n/2,j,n/2,v);
dfs(i,j+n/2,n/2,v);
dfs(i+n/2,j+n/2,n/2,-v);
}
inline void Case_Test()
{
cin>>n;
dfs(1,1,n,1);
rep(i,1,n) rep(j,1,n) cout<<a[i][j]<<" \n"[j==n];
}
文章评论