Just Repeat
题意:
两个人轮流出牌,规定出的牌的颜色不能和对方已经出过的牌一致,谁不能出牌,谁就输了。
思路:
每个人优先出的牌的颜色肯定是场上没出过的, 对方也持有的, 并且两个人手中持有数量最多的牌.对方持有的越多意味着可以封掉
更多的牌, 而自己手里的越多意味着可以防止自己更多的牌被封掉.因此将手里的牌统计好,从大到小分配,最后看手里牌数量即
可判断输赢。可能会卡map.
参考博客:https://blog.csdn.net/sdut_jk17_zhangming/article/details/99441914
代码:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull k1,k2;
const int N=1e5+5;
int n,m;
int a[N],b[N];
struct node{
int x1,x2,x;
}c[N*2];
int cmp(node x,node y){
return x.x>y.x;
}
ull rng() {
unsigned long long k3 = k1, k4 = k2;
k1 = k4;
k3 ^= k3 << 23;
k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26);
return k2 + k4;
}
void read1(ull k1,ull k2, ull mod){
for (int i = 0; i < n; ++i)
a[i+1] = rng() % mod;
}
void read2(ull k1,ull k2,ull mod){
for (int i = 0; i < m; ++i)
b[i+1] = rng() % mod;
}
unordered_map<int,int>mp;
int main(){
int T;
scanf("%d",&T);
while(T--){
int op;
scanf("%d%d%d",&n,&m,&op);
if(op==1){
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<=m;++i)
scanf("%d",&b[i]);
}
else{
ull mod;
cin>>k1>>k2>>mod;
read1(k1,k2,mod);
cin>>k1>>k2>>mod;
read2(k1,k2,mod);
}
mp.clear();
int p=0;
for(int i=1;i<=n;++i){
if(mp[a[i]]==0){
mp[a[i]]=++p;
c[p].x1=1;
c[p].x2=0;
}
else c[mp[a[i]]].x1++;
}
for(int i=1;i<=m;++i){
if(mp[b[i]]==0){
mp[b[i]]=++p;
c[p].x2=1;
c[p].x1=0;
}
else c[mp[b[i]]].x2++;
}
for(int i=1;i<=p;i++)
c[i].x=c[i].x1+c[i].x2;
sort(c+1,c+1+p,cmp);
int sa=0,sb=0,f=0;
for(int i=1;i<=p;++i){
if(c[i].x1==0){
sb+=c[i].x2;
continue;
}
if(c[i].x2==0){
sa+=c[i].x1;
continue;
}
if(f==0)
sa+=c[i].x1;
else sb+=c[i].x2;
f=!f;
}
if(sa>sb)
puts("Cuber QQ");
else puts("Quber CC");
}
return 0;
}