hdu6655 2019杭电多校第七场

这题是全场最水的题。。。榜被带歪了

比赛最后半个小时开始写,然后一开始没想清楚。。。WA了,然后想到问题后,16:52不知道怎么改了。。。。其实稍微仔细推推就很简单了,比赛最后的时间有点紧张。

考虑现在是 Cuber QQ 出牌,他有两种选择,如果他有某张对方很多的牌,那么他出这张牌,就能让对方出不了。第二种选择也是我之前WA的时候没考虑到的情况,他有很多张颜色为  i  的牌,但对面有这张牌,那么我们这轮就出一张颜色为i 的牌,保住我们这么多张 颜色为 i  的牌。

所以我们把双方都有的牌拿出来,按照numa[i]+numb[i]排序,每一个人当前最优策略肯定出一张这个值最大的牌就行了。

边拿边算出双方各剩多少牌,出来再根据先后手情况比较一下就行了

#include<bits/stdc++.h>
#define maxl 200010
using namespace std;
typedef unsigned long long ull;

int n,m,p,cnt,tot,mod,cntc;
ull k1,k2;
bool ans;
int a[maxl],b[maxl],f[maxl];
int numa[maxl],numb[maxl];
int num[maxl];
struct node
{
    int col,num;
}c[maxl];
bool ainb[maxl],bina[maxl];

inline 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;
}

inline bool cmp(const node &x,const node &y)
{
    return x.num<y.num;
}

inline void prework()
{
    cnt=0;
    scanf("%d%d%d",&n,&m,&p);
    if(p==1)
    {
        for(register int i=1;i<=n;++i)
            scanf("%d",&a[i]),num[++cnt]=a[i];
        for(register int i=1;i<=m;++i)
            scanf("%d",&b[i]),num[++cnt]=b[i];
    }
    else
    {
        scanf("%llu%llu%d",&k1,&k2,&mod);
        for(register int i=1;i<=n;++i)
            a[i]=(int)(rng()%mod),num[++cnt]=a[i];
        scanf("%llu%llu%d",&k1,&k2,&mod);
        for(register int i=1;i<=m;++i)
            b[i]=(int)(rng()%mod),num[++cnt]=b[i];
    }
    sort(num+1,num+1+cnt);
    tot=unique(num+1,num+1+cnt)-num-1;
    for(register int i=1;i<=tot;++i)
        numa[i]=numb[i]=0;
    for(register int i=1;i<=n;++i)
    {
        a[i]=lower_bound(num+1,num+1+tot,a[i])-num;
        numa[a[i]]++;
    }
    for(register int i=1;i<=m;++i)
    {
        b[i]=lower_bound(num+1,num+1+tot,b[i])-num;
        numb[b[i]]++;
    }
    cntc=0;
    for(register int i=1;i<=tot;i++)
    {
    	if(numa[i]>0 && numb[i]>0)
			c[++cntc]=node{i,numa[i]+numb[i]}; 
    }
    sort(c+1,c+1+cntc,cmp);
}

inline void mainwork()
{
    int id=1,resa=n,resb=m;
    for(int i=cntc;i>=1;i--)
    {
    	if(id&1)
    		resa--,resb-=numb[c[i].col];
    	else
    		resb--,resa-=numa[c[i].col];
    	id++;
	}
    if(id&1)
    {
        if(resa>resb)
            ans=true;
        else
            ans=false;
    }
    else
    {
        if(resb>resa)
            ans=false;
        else
            ans=true;
    }
}

inline void print()
{
    if(ans)
        puts("Cuber QQ");
    else
        puts("Quber CC");
}

int main()
{
    int t;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        prework();
        mainwork();
        print();
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值