2019杭电暑期多校第七场 J:Just Repeat(贪心+思维)

【题解】

题意:两个人轮流出牌,每次出牌的颜色不能跟对方出过的牌的颜色一致,如果谁出不了牌就输了。

思路:每个人优先出的牌的颜色肯定是:场上没出过的, 对方也持有的,并且两个人手中持有数量最多的牌。对方持有的越多意味着可以封掉更多的牌,而自己手里的越多意味着可以防止自己更多的牌被封掉。因此,对所有的两个人手里都持有的颜色的牌数进行统计, 从大到小依次分配给第一、二个玩家。如果此时第一个玩家手里的牌数 > 第二个玩家,则第一个玩家胜利, 否则第二个玩家胜利。 到此为止,问题转换成另一个问题:有一堆东西,每个东西有两个值,A 拿到这个东西的收益是 ai,B 拿到的收益是 bi,两人依次拿,求最优策略下两人的各自收益。这是一个经典问题,答案就是按照 ai + bi 排序模拟一下就好了。

【代码】

#include
using namespace std;
typedef unsigned long long ULL;
typedef pair P;
const int N=2e5+10;
P A[N],B[N],C[N];
ULL a[N];
ULL k1,k2;
ULL rng(){
    ULL k3=k1,k4=k2;k1=k4;k3^=k3<<23;k2=k3^k4^(k3>>17)^(k4>>26);
    return k2+k4;
}
void init(P T[],int& n,int p)
{
    if(p==1){
        for(int i=0;ib.first+b.second;
}
int main()
{
    int T; scanf("%d",&T);
    while(T--){
        int n,m,p; scanf("%d%d%d",&n,&m,&p);
        init(A,n,p); init(B,m,p);
        int SA=0,SB=0,k=0;
        int p1=0,p2=0;
        while(p1B[p2].first)) SB+=B[p2++].second; //如果B[p2].first比较小,那么说明不可能有相同颜色了
            else if(p2==m||(p1SB) puts("Cuber QQ"); //Cuber QQ 先手
        else puts("Quber CC");
    }
	return 0;
}

 

你可能感兴趣的:(2019杭电暑期多校第七场 J:Just Repeat(贪心+思维))