A sooo Torturous Problem
R o o f C o n s t r u c t i o n Roof \ Construction Roof Construction
题意:
给定一个整数 n n n代表一个从 0 0 0到 n − 1 n-1 n−1的序列(此处的序列指 0 , 1 , 2 , … , n − 1 0,1,2,\dots ,n-1 0,1,2,…,n−1),找到一种排序方式使每相邻两位数字按位异或之后整个异或值序列的最大值最小。
思路:
整个序列异或值最大值的最小值是最高位为
1
1
1,其他位都是
0
0
0的情况。抽象解释一下:如果求异或最大值的话肯定最高位是
1
1
1,其他位不确定,因为总会有最高位为
1
1
1的数字与最高位是
0
0
0的数相邻,所以我们要做的就是将除最高位的其他位都变为
0
0
0,这就是最大值的最小值。
说白了就是这个最小值是
2
k
2^k
2k,也就是
(
100
…
00
)
B
(100\dots 00)_B
(100…00)B,我们要做的就是把
0
0
0位数最多的数(找最大的
k
k
k)与
0
0
0相邻,当然也有其他方式实现这个最小值,不过这种最好操作。
#include <bits/stdc++.h>
using namespace std;
signed main(){
int t,n,k; cin >> t;
while(t--)
{
cin >> n;
while(1<<(k+1) <=n-1) k++;
for(int i=(1<<k)-1;i>=0;i--)
cout << i << ' ';
for(int i=1<<k;i<n;i++)
cout << i << ' ';
cout << '\n';
}
return 0;
}
对于某憨憨>.<来说还有一个点需要注意…
代码中的 k k k在跳出循环时其实是 最后一个满足条件的 k k k值 + 1 +1 +1… Q A Q QAQ QAQ