题目链接:HDU6655 Just Repeat
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Problem Description
When Cuber QQ was chatting happily in a QQ group one day, he accidentally noticed that there was a counterfeit of him, who stole his avatar and mimicked his tone, and more excessively, had a nickname "Quber CC", which was sarcastic to him. So Cuber QQ decided to play a little game with this Quber CC, and their bet was, whoever lost the game would have to do something really humiliating in front of everyone in the QQ group.
The game is like this. It's a traditional card game. Cuber QQ will play first. Cuber QQ, and his opponent (Quber CC of course), will each possess a hand of cards. There is no number (or rank if you prefer) on the card, but only color (or suit if you prefer). The players play cards alternatively, each player can only play one card in each turn. An additional rule is that, a player must not play a card with the same color as any card which has been played by his/her opponent, but coincidence with a card played by himself/herself is acceptable.
The player who can't play any card loses. This might due to the fact that he/she has cards but he cannot play any due to the game rules, or he doesn't have any cards any more. As a game played between civilized people, the game will be played in a completely transparent manner, where Cuber QQ and Quber CC know exactly what's left in their opponent's hand.
It's now a game attracting thousands of eyes, and you decided to invent a predictor whose job is to predict "who will win if both players play smart" to excite the audience.Input
The first line of the input is a positive integer t, denoting the number of test cases.
Then follows t test cases, each test case starts with space-separated integers n, m, p (1≤n,m≤105, p∈{1,2}). Generally speaking, this should be followed by two lines of integers a1,a2,…,an and b1,b2,…,bm, denoting the colors of Cuber QQ's hand and Quber CC's hand, respectively. Unfortunately, as it turns out, the input will be the bottleneck in that case. So we introduce p to deal with this problem.
For p=1, there follows two lines, where the first line is a1,a2,…,an and the second line is b1,b2,…,bm, all space separated and 0≤ai,bi<109.
For p=2, there follows two lines, which are k1,k2,mod (0≤k1,k2<264, 1≤mod≤109) to generate {ai} and {bi}, respectively.
Here are some instructions on how to generate {ai}, {bi} with k1,k2,mod, which you've probably seen before, somehow:unsigned long long k1, k2; unsigned long long rng() { unsigned long long k3 = k1, k4 = k2; k1 = k4; k3 ^= k3 << 23; k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26); return k2 + k4; } // generate read(k1, k2, mod); for (int i = 0; i < n; ++i) a[i] = rng() % mod; read(k1, k2, mod); for (int i = 0; i < m; ++i) b[i] = rng() % mod; Also, the sum of n+m for p=1 does not exceed 5⋅105; the sum of n+m from all test cases does not exceed 107.
Output
For each test case, predict the winner: "Cuber QQ" or "Quber CC".
Sample Input
2
6 7 1
1 1 4 5 1 4
1 9 1 9 8 1 0
10 20 2
1 2 10
1 2 10
Sample Output
Cuber QQ
Quber CC
题意:
QQ小方两个人玩纸牌游戏,纸牌的信息只有颜色(数字相同就表示颜色相同),规则是: 我能出的牌不能和任何对方出过的牌颜色相同,不能出牌就表示输了游戏,游戏过程中所有牌的颜色都是已知的,无论是对方还是自己。
分析:
首先我们可以想到的是,出牌的最优策略是未出现过的颜色,并且它的数量是还没出过的颜色里最多的,对方手里的数量越多,他不能出的数量越多,我手里的数量就是这种颜色对我的贡献。
具体在代码里有注释
#include<bits/stdc++.h>
#define ull unsigned long long
#define ll long long
using namespace std;
const int maxn=2e5+7;
struct node{int fst,scd;} a[maxn],b[maxn],c[maxn];
ull k1,k2;
ull ky()
{
ull k3=k1,k4=k2;
k1=k4;
k3^=k3<<23;
k2=k3^k4^(k3>>17)^(k4>>26);
return k2+k4;
}
bool szd(node A,node B) {return A.fst+A.scd>B.fst+B.scd;}
int awsl(node a[],int n,int p)
{
int tmp[maxn],cnt=0;
if(p==2)
{
int mod;scanf("%llu%llu%d",&k1,&k2,&mod);
for (int i=0;i<n;i++) tmp[i]=ky()%mod;
}
else for (int i=0;i<n;i++) scanf("%d",&tmp[i]);
sort(tmp,tmp+n);
for (int i=0;i<n;)
{
int res=i+1;
while(tmp[res]==tmp[i] && res<n) res++;//忘记判断不能超过n还wa了一发
a[cnt++]={tmp[i],res-i};
i=res;
}
return cnt;
}
void rua()
{
int n,m,p;scanf("%d%d%d",&n,&m,&p);
n=awsl(a,n,p);m=awsl(b,m,p);
int p1=0,p2=0,tot=0;
int s1=0,s2=0;
while (p1<n || p2<m)
{
if(p1<n && p2<m && a[p1].fst==b[p2].fst) c[tot++]={a[p1++].scd,b[p2++].scd};//暂存 最后处理
else if(p1==n || (a[p1].fst>b[p2].fst && p2<m)) s2+=b[p2++].scd;//b有a没有的 直接算贡献
else if(p2==m || (a[p1].fst<b[p2].fst && p1<n)) s1+=a[p1++].scd;//同上
}
sort(c,c+tot,szd);//按照对两人贡献和排序
for (int i=0;i<tot;i++)
{
if(i%2==0) s1+=c[i].fst;//QQ小方先拿
else s2+=c[i].scd;
}
if(s1>s2) printf("Cuber QQ\n");else printf("Quber CC\n");
}
int main()
{
int qwq;scanf("%d",&qwq);
while (qwq--) rua();
return 0;
}