A题是最水的一题了。
题意:你有两个序列,都是0,1,2,,,,n-1,现在,你需要让他们一一匹配,使得所有匹配在一起的数的亦或和相加最小。
输入的是n,输出的是一个序列,他表示0到 n-1 中每个数索匹配到的数字。
思路:从大到小遍历每一个数字k,每次取最大的与k异或为0的数,(若 k 为 13,则二进制位 1101,则与他最大的异或和为0的数为2,即:去掉第一位1 剩下的位数取反),若i已经被匹配,则跳过。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long ll;
using namespace std;
ll a[500000+20],n;
void init()
{
for(int i=0;i<n;i++)
a[i]=i;
memset(a,-1,sizeof(a));
}
ll my_find(int k)
{
for(int i=0;i<20;i++)
if(1<<i>k)
return 1<<i;
return -1;
}
int main()
{
cin>>n;
init();
for(int i=n-1;i>=0;i--)
{
if(a[i]!=-1)
continue;
ll t=my_find(i);
a[i]=t-1-i;
a[t-1-i]=i;
}
for(int i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}