HDU 6655 Just Repeat 贪心思想

据说比较水

所以就补一下题目咯

但是 康康这提交 哭了啊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 记得转换类型……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值