据说比较水
所以就补一下题目咯
但是 康康这提交 哭了啊orz
题目大意:
QQ和CC一起打牌
一共有 t 局,每次都是QQ先出牌
每一局QQ有 n 张牌 CC有 m 张牌
如果QQ出的牌的点数,CC也有,那么CC就不能出QQ已经出过的牌
谁没牌出谁就输了
求两人都足够聪明的情况下,谁获胜?
思路:
先考虑两个人都有的牌
因为QQ出过的牌CC不能再出
即 可以限制对方出牌
将 numa[i] + numb[i] 从大到小排序
就可以满足两人都在各自角度拿最多的那部分
剩下的对方没有的牌就都可以出
两者都有的取自己那部分 + 只有自己有的那部分
比较大小即可
代码如下:
#include <stdio.h>
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
const int maxn = 200005;
int num[maxn], numa[maxn], numb[maxn], a[maxn], b[maxn];
int n, m, p;
unsigned long long k1, k2;
int mod;
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);
}
void read1(ull k1, ull k2, int mod)
{
for (int i = 0; i < n; ++i) {
a[i] = (int)(rng() % mod);
}
}
void read2(ull k1, ull k2, int mod)
{
for (int i = 0; i < m; ++i) {
b[i] = (int)(rng() % mod);
}
}
struct node {
int num;
int sum;
} ans[maxn];
bool cmp(int x, int y)
{
return x > y;
}
bool cmp2(node a, node b)
{
if (a.sum == b.sum) {
return a.num < b.num;
} else {
return a.sum > b.sum;
}
}
int main()
{
int t, x, y;
scanf("%d", &t);
while (t--) {
// memset(CC, 0, sizeof CC);
// memset(QQ, 0, sizeof QQ);
memset(num, 0, sizeof num);
memset(numa, 0, sizeof numa);
memset(numb, 0, sizeof numb);
// memset(a, 0, sizeof a);
// memset(b, 0, sizeof b);
memset(ans, 0, sizeof ans);
scanf("%d%d%d", &n, &m, &p);
if (p == 1) {
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for (int i = 0; i < m; i++) {
scanf("%d", &b[i]);
}
} else {
scanf("%llu%llu%d", &k1, &k2, &mod);
read1(k1, k2, mod);
scanf("%llu%llu%d", &k1, &k2, &mod);
read2(k1, k2, mod);
}
// for (int i = 0; i < n; i++) {
// printf("%d ", a[i]);
// }
// printf("&&&\n");
// for (int i = 0; i < m; i++) {
// printf("%d ", b[i]);
// }
// printf("***\n");
// printf("n = %d,m = %d\n",n,m);
int cnt = 0;
for (int i = 0; i < n; i++) {
num[cnt++] = a[i];
}
for (int i = 0; i < m; i++) {
num[cnt++] = b[i];
}
sort(num, num + cnt);
// for (int i = 0; i < cnt; i++) {
// printf("%d ", num[i]);
// }
// printf("*** \n");
int s = unique(num, num + cnt) - num;
for (int i = 0; i < n; i++) {
a[i] = lower_bound(num, num + s, a[i]) - num;
numa[a[i]]++;
// printf("%d &",a[i]);
}
// puts("");
for (int i = 0; i < m; i++) {
b[i] = lower_bound(num, num + s, b[i]) - num;
numb[b[i]]++;
// printf("%d *",b[i]);
}
// puts("");
int pos = 0, AA = 0, BB = 0;
for (int i = 0; i < s; i++) {
// printf("%d ## %d\n",numa[i],numb[i]);
if (numa[i] > 0 && numb[i] > 0) {
ans[pos].num = i;
ans[pos].sum = numa[i] + numb[i];
pos++;
} else if (numa[i] > 0) {
AA += numa[i];
} else if (numb[i] > 0) {
BB += numb[i];
}
}
sort(ans, ans + pos, cmp2);
int A = 0;
int B = 0;
// for(int i=0;i<pos;i++)
// {
// printf("%d %d###\n",ans[i].num,ans[i].sum);
// }
for (int i = 0; i < pos; i++) {
if (i % 2 == 0) {
A += numa[ans[i].num];
} else {
B += numb[ans[i].num];
}
}
// printf("%d %d &&\n", AA, A);
// printf("%d %d ** \n", BB, B);
if ((AA + A) > (BB + B)) {
printf("Cuber QQ\n");
} else {
printf("Quber CC\n");
}
}
return 0;
}
/*
2
4 8 1
5 3 3 2
4 3 2 3 5 1 7 6
6 7 1
1 4 2 5 2 3
4 7 8 8 5 2 3
*/
注意:k1,k2是 unsigned long long 而mod是 int 记得转换类型……