建通道
建通道
http://www.nowcoder.com/questionTerminal/1ad2f38ae0444c9ab668c0db4a000ea7
建通道
https://ac.nowcoder.com/acm/contest/3003/I
算是考察位运算吧?
lowbit(0)=0,连接代价为0,可进行去重操作,去掉与之权值相等的
如果最后只剩一个 则直接输出 0
x=vi^vj
!=1时,找最小位的二进制k(在该位上,所有权值中 1 与 0 同时并存(因1^0=1),若同时并存,所有通道间可
进行1-0 0-1 全部连通,若仅存在1或仅存在0,就没有通道能够相连)
#pragma warning (disable :4996)
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10;
ll W[N];
map<int, int> vis;
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lld", &W[i]);
if (vis[W[i]]) { //权值一样,lowbit()为0,连接代价为0,去重
i--, n--;
}
vis[W[i]] = 1;
}
if (n == 1) {
cout << "0" << endl; //都相同
return 0;
}
ll cost = 0;
ll ans = 1;
for (int i = 1;; i++) {
int t1 = 0, t2 = 0; //当前位是否存在1 和 0同时并存,若存在则可一次0-1 1-0 全部连通,不存在则该位无法
for (int j = 1; j <= n; j++) {
int tmp = W[j] & 1;
W[j] >>= 1; //右移一位 /=2
if (tmp == 1) t1 = 1;
if (tmp == 0) t2 = 1;
}
if (t1 && t2) {
cost = ans * (n - 1) * 1ll;
break;
}
ans *= 2ll;
}
cout << cost << endl;
}
查看10道真题和解析