测试地址:Harmony Analysis
题目大意: 有
2
k
2^k
2k个
2
k
2^k
2k维向量,这些向量的每一维都是
1
1
1或
−
1
-1
−1,要求构造出一种情况使得,对任意两个向量,它们的内积(
∑
a
i
⋅
b
i
\sum a_i\cdot b_i
∑ai⋅bi)为
0
0
0。
做法: 本题需要用到分治+构造。
首先看
k
=
1
k=1
k=1的情况,显然解是这样的:
+
1
,
+
1
+1,+1
+1,+1
+
1
,
−
1
+1,-1
+1,−1
那么我们能不能用
k
=
1
k=1
k=1的情况推理出
k
=
2
k=2
k=2的情况呢?注意到我们可以把边长为
2
k
2^k
2k的矩阵分成
4
4
4块边长为
2
k
−
1
2^{k-1}
2k−1的矩阵,如果这些矩阵都是
k
−
1
k-1
k−1时的解或者相反数,我们就能保证上半和下半部分内部向量对的内积为
0
0
0。关键是如何保证一个在上半,另一个在下半的向量对内积为
0
0
0。
我们可以仿照上面
k
=
1
k=1
k=1的形式,在当前解中填入上一层次的解和其相反数。这样的话,跨越中线的向量对的左半部分内积和右半部分内积直接抵消,这样就可以保证满足条件了。
以下是本人代码:
#include <bits/stdc++.h>
using namespace std;
int k,a[1010][1010];
int main()
{
scanf("%d",&k);
a[0][0]=1;
for(int i=1;i<=k;i++)
for(int x=0;x<(1<<(i-1));x++)
for(int y=0;y<(1<<(i-1));y++)
{
a[x+(1<<(i-1))][y]=a[x][y];
a[x][y+(1<<(i-1))]=a[x][y];
a[x+(1<<(i-1))][y+(1<<(i-1))]=-a[x][y];
}
for(int i=0;i<(1<<k);i++)
{
for(int j=0;j<(1<<k);j++)
printf("%c",(a[i][j]>0)?'+':'*');
printf("\n");
}
return 0;
}