P8826 [传智杯 #3 初赛] 游戏(征集数据)
题目描述
清蒸鱼是一个从未被击败的炽蓝仙野游戏者。有一天他遇到了这么一个游戏:
给定一个长度为 nnn 的数组 aaa。同时定义 count(x)count(x)count(x) 为 xxx 在二进制下的 111 的个数。
现在清蒸鱼每次可以进行如下两种操作:
-
选择两个数 ai,aja_i, a_jai,aj,并且必须满足 count(aixoraj)=1count(a_i \operatorname{xor} a_j)=1count(aixoraj)=1,将它们中的任意一个从数组中消去,代价为 C1C_1C1。
-
选择两个数 ai,aja_i, a_jai,aj,并且必须满足 count(aixoraj)>1count(a_i \operatorname{xor} a_j) > 1count(aixoraj)>1,将它们中的任意一个从数组中消去,代价为 C2C_2C2。
现在你想知道,最少付出多少的代价,能让这个数组被消到只剩一个数。
输入格式
第一行一个整数 nnn,表示数组大小。
第二行两个整数 C1,C2C_1, C_2C1,C2,意义如题所示。
第三行共 nnn 个整数,描述了数组 aaa。
输出格式
一行一个整数,表示最小代价。
输入输出样例 #1
输入 #1
4
5 10
1 2 3 4
输出 #1
20
说明/提示
对于 20%20\%20% 的数据,满足 n=10n = 10n=10;
对于另外 20%20\%20% 的数据,满足 aaa 中的元素为一个 [1,n][1, n][1,n] 的排列;
对于 100%100\%100% 的数据,满足 1≤n≤1041 \leq n \leq {10}^41≤n≤104,1≤C1,C2,a≤1091\le C_1, C_2, a \le {10}^91≤C1,C2,a≤109,aaa 中的元素互不相同。
C++实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e4+5;
int n,c1,c2,a[N],f[N],ans;
int getf(int u){
if(f[u]==u)return u;
return f[u]=getf(f[u]);
}
int calc(int x){
return x&(-x);
}
void merge(int x,int y){
x=getf(x),y=getf(y);
if(x==y)return;f[x]=y,ans++;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> n >> c1 >> c2;
for(int i =1;i <= n;i++)cin >> a[i],f[i]=i;
for(int i = 1;i <= n;i++){
for(int j = i+1;j <= n;j++){
int flag=0,val=(a[i]^a[j]);
if((val||n<=10)&&calc(val)==val)flag=1;
if(c1<c2&&flag)merge(i,j);
else if(c1>c2&&!flag)merge(i,j);
}
}if(c1>c2)swap(c1,c2);
cout << c1*ans+(n-1-ans)*c2;
return 0;
}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容