传送门:Just Repeat
题意大概是,a、b手中各有带有颜色的n、m张牌,a先手,双方轮流出牌,一方出过的颜色,对方不可出,无法出牌者败。那么,双方优先出的牌的颜色,一定是场上还没出过、对方同样持有且双方持有总数最大的,因为这样,就能保证自己能够出更多的牌或能让对方少出更多的牌,从而增大胜算。所以,只要统计双方都有的颜色的牌的总数,按照数量逆序排序,从a开始轮流分配,即表明该颜色是该方可打出的,最后统计双方可打出的牌的数量,如果a可打出的牌数大于b,则a胜,否则b胜。
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5+5;
int t, n, m, p, mod;
ull k1, k2;
int a[maxn], b[maxn];
typedef pair<int, int> PAIR; //用于vector,方便map排序的type
bool cmp(const PAIR& x, const PAIR& y){ //map转化为vector后,按值排序的cmp函数
if(x.second != y.second)
return x.second > y.second;
return x.first < y.first;
}
ull rng() {
ull k3 = k1, k4 = k2;
k1 = k4;
k3 ^= k3 << 23;
k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26);
return k2 + k4;
}
void read(){
cin >> n >> m >> p;
if(p == 1){
for(int i = 0; i < n; ++i)
cin >> a[i];
for(int i = 0; i < m; ++i)
cin >> b[i];
}else{
cin >> k1 >> k2 >> mod;
for (int i = 0; i < n; ++i)
a[i] = rng() % mod;
cin >> k1 >> k2 >> mod;
for (int i = 0; i < m; ++i)
b[i] = rng() % mod;
}
}
void solve(){
unordered_map<int, int> ma, mb, mc; //ma、mb:a、b都有的颜色中两者分别持有的数量;mc:ma[i]+mb[i],作为排序的权重。用unordered_map速度更快
int ln = n, lm = 0; //a、b剔除都有的颜色的手牌后,剩余的手牌数量,也就是单独所有的颜色的总数量。这里的初始化不同是因为后续计算方式不同
for(int i = 0; i < n; ++i){
if(!ma.count(a[i])) ma[a[i]] = 1; //如果当前颜色尚未记录,则置为1
else ++ma[a[i]]; //否则累加,计算持有的数量
}
for(int i = 0; i < m; ++i){
if(!ma.count(b[i])) ++lm; //如果a的手牌中没有b[i]的颜色,说明b[i]的颜色为b单独所有
else if(!mc.count(b[i])){ //否则说明a的手牌中也有b[i]的颜色
ln -= ma[b[i]]; //此时,由于b[i]颜色并非a所独有,所以要减去a持有b[i]颜色的手牌数,得到a单独所有的颜色的总数
mb[b[i]] = 1; //表明b持有a也有的颜色的手牌
mc[b[i]] = ma[b[i]]+1; //计算某个a、b都有的颜色的总数
}else{
++mb[b[i]];
++mc[b[i]];
}
}
vector<PAIR> vec(mc.begin(), mc.end()); //将map转化为vector,方便排序
sort(vec.begin(), vec.end(), cmp); //按值排序,也就是按照a、b都有的各个不同颜色的数量排序
bool flag = 1; //标记此时轮到a
for(vector<PAIR>::iterator it = vec.begin(); it != vec.end(); ++it){ //从牌的数量从大到小轮流分配
int index = (*it).first;
if(flag) ln += ma[index]; //轮到a
else lm += mb[index]; //轮到b
flag = !flag;
}
if(ln > lm) cout << "Cuber QQ\n"; //a的手牌更多,则a赢
else cout << "Quber CC\n"; //否则b赢
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> t;
while(t--){
read();
solve();
}
return 0;
}