hdu多校第七场 6655 Just Repeat 博弈

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6655

题意:

小C和小Q玩起了打牌的游戏,两个人轮流出牌,小C先出,小C手中有n张牌,小Q有m张,两个人知道对方手中有什么牌,如果对手已经出过了这个数字,那么自己就不能再出这种数字的牌,问最后谁先不能出牌。

做法:

很明显如果一张牌只有自己有,那么这个肯定是自己能出的不用着急,关键的就是两个人共同有的牌。我们假设两个人共有10个1,8个2,小C现在有1个1和7个2并且他出,那么它肯定会先出1,这样的话对方就有9张牌不能出,哪怕自己之后的7个2都不能出,也是赚的。所以我们记录两个人都有的牌的总数,并且从大到小枚举,分别把牌给对应的人,最后再判断就好了。

严格说起来好像这道题也不算博弈了,就是个想法,贪心去做就好了,赛上的时候榜偏了导致这个题并没有被我们看到…无奈╮(╯▽╰)╭

代码:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define ll long long
using namespace std;
const int maxn=100009;
typedef pair<int,int> pii;
unordered_map<int,int> mp;
int num[2][maxn<<1],a[maxn],b[maxn],mod;
int sum[2],n,m,p,ct;
vector<int> ve[maxn<<1];
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;
}
int read(){ int ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
int gain(int x){
    if(!mp[x]) mp[x]=++ct;
    return mp[x];
}
void init(){
    rep(i,1,ct) num[0][i]=num[1][i]=0;
    ct=0;
    mp.clear();
}
int main(){

    int t;scanf("%d",&t);
    while(t--){
        init();
        scanf("%d%d%d",&n,&m,&p);
        sum[0]=n,sum[1]=m;
        if(p==1){
            rep(i,1,n) {
                a[i]=read();
                int x=gain(a[i]);
                num[0][x]++;
            }
            rep(i,1,m) {
                b[i]=read();
                int x=gain(b[i]);
                num[1][x]++;
            }
        }
        else{
            cin>>k1>>k2>>mod;
            rep(i,1,n) {
                a[i]=rng()%mod;
                int x=gain(a[i]);
                num[0][x]++;
            }
            cin>>k1>>k2>>mod;
            rep(i,1,m) {
                b[i]=rng()%mod;
                int x=gain(b[i]);
                num[1][x]++;
            }
        }
        int up=0;
        rep(i,1,ct){
            if(num[0][i]&&num[1][i]){
                sum[0]-=num[0][i];
                sum[1]-=num[1][i];
                int mma=num[0][i]+num[1][i];
                ve[mma].push_back(num[0][i]);
                up=max(up,mma);
            }

        }
        p=0;
        for(int i=up;i>=1;i--){
            for(auto v :ve[i]){
                if(p==0) sum[0]+=v;
                else sum[1]+=i-v;
                p^=1;
            }
            ve[i].clear();
        }
        if(sum[0]>sum[1]) printf("Cuber QQ\n");
        else printf("Quber CC\n");
    }
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值