2020牛客寒假算法基础集训营2
题意:
分析:
如果两个数相等那么他们的异或值为0,所以直接把他们连起来即可
考虑所有不同的数(cnt个):
因为花费的值为 x 二进制最低位 1 对应的值,那么在越低的位把他们异或得到1,花费越小,那么所有的数中只要在第k位,既有0又有1,那么就把是0的和是1的相连,把是1的和是0的相连,需要花费(1<<k)*(cnt-1)
我们使k(0<=k<=30)最小即可
代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <map>
#include <queue>
#include <set>
#define Pll make_pair
using namespace std;
typedef long long ll;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int phi=1e9+6;
int a[maxn],b[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+n+1);
int cnt=0;
b[++cnt]=a[1];
for(int i=2;i<=n;i++) if(a[i]!=a[i-1])b[++cnt]=a[i];
if(cnt==1){//所有数全部相同
printf("0\n");
return 0;
}
for(int i=0;i<=30;i++){
int k=0;
for(int j=1;j<=cnt;j++)if((b[j]>>i)&1)k++;//第i位是1的个数
if(k>0&&k<cnt){
printf("%lld\n",1ll*(1<<i)*(cnt-1));
return 0;
}
}
return 0;
}
/*
*/