I:建通道 (思维,位运算)

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;
}
/*

 */
发布了142 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44091178/article/details/104211035
今日推荐