2019杭電多校第七場1010:Just Repeat

Just Repeat

題意:

兩個人輪流出牌,規定出的牌的顏色不能和對方已經出過的牌一致,誰不能出牌,誰就輸了。

思路:

每個人優先出的牌的顏色肯定是場上沒出過的, 對方也持有的, 並且兩個人手中持有數量最多的牌.對方持有的越多意味着可以封掉 

更多的牌, 而自己手裏的越多意味着可以防止自己更多的牌被封掉.因此將手裏的牌統計好,從大到小分配,最後看手裏牌數量即

可判斷輸贏。可能會卡map.

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

代碼:

#include<bits/stdc++.h>
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_map<int,int>mp;
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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章