2019杭电多校第七场1010:Just Repeat

Just Repeat

题意:

两个人轮流出牌,规定出的牌的颜色不能和对方已经出过的牌一致,谁不能出牌,谁就输了。

思路:

每个人优先出的牌的颜色肯定是场上没出过的, 对方也持有的, 并且两个人手中持有数量最多的牌.对方持有的越多意味着可以封掉 

更多的牌, 而自己手里的越多意味着可以防止自己更多的牌被封掉.因此将手里的牌统计好,从大到小分配,最后看手里牌数量即

可判断输赢。可能会卡map.

参考博客:https://blog.csdn.net/sdut_jk17_zhangming/article/details/99441914

代码:

#include
using namespace std;
typedef unsigned long long ull;
ull k1,k2;
const int N=1e5+5;
int n,m;
int a[N],b[N];
struct node{
	int x1,x2,x;
}c[N*2];
int cmp(node x,node y){
	return x.x>y.x;
}
ull 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, ull mod){
	for (int i = 0; i < n; ++i)
    	a[i+1] = rng() % mod;
}
void read2(ull k1,ull k2,ull mod){
	for (int i = 0; i < m; ++i)
    	b[i+1] = rng() % mod;
}
unordered_mapmp;
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int op;
		scanf("%d%d%d",&n,&m,&op);
		if(op==1){
			for(int i=1;i<=n;++i)
				scanf("%d",&a[i]);
			for(int i=1;i<=m;++i)
				scanf("%d",&b[i]);
		}
		else{
			ull mod;
			cin>>k1>>k2>>mod;
			read1(k1,k2,mod);
			cin>>k1>>k2>>mod;
			read2(k1,k2,mod);
		}
		mp.clear();
		int p=0;
		for(int i=1;i<=n;++i){
			if(mp[a[i]]==0){
				mp[a[i]]=++p;
				c[p].x1=1;
				c[p].x2=0;
			}
			else c[mp[a[i]]].x1++;
		}
		for(int i=1;i<=m;++i){
			if(mp[b[i]]==0){
				mp[b[i]]=++p;
				c[p].x2=1;
				c[p].x1=0;
			}
			else c[mp[b[i]]].x2++;
		}
		for(int i=1;i<=p;i++)
			c[i].x=c[i].x1+c[i].x2;
		sort(c+1,c+1+p,cmp);
		int sa=0,sb=0,f=0;
		for(int i=1;i<=p;++i){
			if(c[i].x1==0){
				sb+=c[i].x2;
				continue;
			}
			if(c[i].x2==0){
				sa+=c[i].x1;
				continue;
			}
			if(f==0)
				sa+=c[i].x1;
			else sb+=c[i].x2;
			f=!f;
		}
		if(sa>sb)
			puts("Cuber QQ");
		else puts("Quber CC");
	}
	return 0;
}

你可能感兴趣的:(多校)