欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[大模拟]梭哈

程序员文章站 2022-03-14 19:47:20
...

描述 Alice 和 Mukyu 最近偶然得到了一本写有一种叫做梭哈的扑克游戏的规则的说明书,据其所述,梭哈是一种使用黑桃、红心、
梅花、方片的 A 到 K 共 52 张牌(没有大小王)来进行的扑克牌游戏。

不幸的是,规则说明中有关整个游戏的进行方式的部分被撕掉了, Alice 和 Mukyu 从残 存的部分只得知了“手牌上限是 5
张”这一消息,所以他们决定每次直接给两人各发 5 张牌, 判定谁的手牌比较大,说明书中关于手牌大小判定的信息如下:

所有五张牌的组合,按以下秩序,由大至小排行分为不同牌型:

1、同花顺(Straight Flush):同一花色,顺序的牌。 例: Q♦ J♦ 10♦ 9♦ 8♦;

2、四条(Four of a Kind):有四张同一点数的牌。 例: 10♣ 10♦ 10♥ 10♠ 9♥;

3、满堂红(Full House):三张同一点数的牌,加一对其他点数的牌。 例: 8♣ 8♦ 8♠ K♥ K♠;

4、同花(Flush):五张同一花色的牌。 例: A♠ K♠ 10♠ 9♠ 8♠;

5、顺子(Straight):五张顺连的牌。 例: K♦ Q♥ J♠ 10♦ 9♦;

6、三条(Three of a kind):有三张同一点数的牌。 例: J♣ J♥ J♠ K♦ 9♠;

7、两对(Two Pairs):两张相同点数的牌,加另外两张相同点数的牌。 例: A♣ A♦ 8♥ 8♠ Q♠;

8、一对(One Pair):两张相同点数的牌。 例: 9♥ 9♠ A♣ J♠ 8♥;

9、无对(Zilch):不能排成以上组合的牌,以点数决定大小。例: A♦ Q♦ J♠ 9♣ 8♣。
若牌型一样则利用点数和花色决定胜负。(点数优先) 点数的顺序(从大至小)为: A>K>Q>J>10>9>8>7>6>5>4>3>2。(注:当
5 张手牌是 5 4 3 2 A 的时候, A 可以看作最小的牌,此时的牌型仍然为顺子,是顺子里面最小的一个)。

花色的顺序(大至小)为:黑桃(♠)>红心(♥)>梅花(♣)>方块(♦)。

举例说明:

1、 Q♦ J♦ 10♦ 9♦ 8♦ > 8♣ 8♥ 8♠ K♥ K♠ (前者牌型为同花顺,比后者大);

2、 9♣ 9♦ 9♠ Q♥ Q♠ > 8♣ 8♦ 8♠ K♥ K♠ (两者牌型均为满堂红,比较牌型中三张同一点 数的牌 9 比 8 大);

3、 A♣ A♦ 8♥ 8♠ Q♠ > A♠ A♥ 7♥ 7♠ K♠ (两者牌型均为两对,且最大的对子相同,此时 比较次大的对子, 8 比
7 大);

4、 A♠ Q♠ J♥ 9♥ 8♥ > A♦ Q♦ J♠ 9♣ 8♣ (两者牌型均为无对,所有数码均相同,此时比 较最大牌的花色, A♠ >
A♦)。

5、 4♠ 4♥ A♦ Q♦ 5♦ > 4♣ 4♦ A♠ Q♠ 5♠ (两者牌型均为一对,所有数码均相同,此时对 4
为牌型里最大的部分,因此比较 4♠ > 4♣)

尽管 Alice 和 Mukyu 都可以轻易的判断出结果,他们还是想见识一下现代科技的力量。

输入 第一行包含一个正整数 N,表示有 N 组测试数据

每组测试数据包含 10 行,前 5 行每行用两个整数描述一张 Alice 手上的牌, 第一个数 表示牌的数码(1 表示 A, 13 表示
K),第二个数表示牌的花色(1 表示黑桃, 2 表示红心, 3 表示梅花, 4 表示方块)。

后 5 行每行用两个整数描述 Mukyu 手上的牌,格式同上。

输出 对于每组测试数据,在单独的一行内输出 Alice 或 Mukyu,表示谁能赢。

样例输入
1
1 3
5 3
4 3
3 3
2 3
6 1
10 4
7 1
8 1
9 2

样例输出
Alice

提示
样例说明
Alice 的手牌构成同花顺,而 Mukyu 的手牌仅构成普通顺子。
数据范围与约定
对于 10%的数据,保证输入的全部牌型都是无对。
对于另外 30%的数据,保证输入的全部牌型都是顺子、同花或同花顺。
对于 100%的数据,保证 N ≤ 100000。
C++选手如果使用 cin 读入数据很可能因此超时,推荐使用 scanf/printf。

分析:
模拟吧,没什么好说的

代码:


#include<bits/stdc++.h>
using namespace std;
struct card{int col,num;}c[3][8];
bool cmp(card a,card b){if(a.num==b.num) return a.col>b.col;return a.num<b.num;}
int par=0,nu[5];
inline int check(int v){
	int kind=0,f=1;
	sort(c[v]+1,c[v]+6,cmp);
	for(int i=2;i<=5;i++) {
		if(c[v][i].num==c[v][i-1].num+1 || (c[v][i].num==14 && c[v][i-1].num==5)){
			if(i==5 && c[v][i].num==14 && c[v][i-1].num==5) {for(int i=5;i>=2;i--) c[v][i].num=c[v][i-1].num;c[v][1].num=1;}
		}
		else {f=0;break;}}
	if(f) kind=5;f=1;
	for(int i=1;i<=5;i++) if(c[v][i].col!=c[v][1].col) f=0;
	if(f) {if(kind==5) return 9;else return 6;}
	if(kind) return kind;
	int mid=c[v][3].num,tot=0;
	for(int i=1;i<=5;i++) if(c[v][i].num==mid) ++tot;
	if(tot==4) return 8;
	else if(tot==3){
		int cnt=0,x=0,y=0;
		for(int i=1;i<=5;i++) if(c[v][i].num!=mid) {if(!x) x=c[v][i].num;else y=c[v][i].num;}
		if(x==y) return 7;
		else return 4;
	}
	par=0;
	for(int i=2;i<=5;i++){
		if(c[v][i].num==c[v][i-1].num) nu[++par]=c[v][i].num;
	}
	if(par==2) return 3;
	else if(par==1) return 2;
	return 1;
}
int cpr(int k){ 
	if(k==1 || k==6 || k==9 || k==5){
		for(int i=5;i>=1;i--){
			if(c[1][i].num>c[2][i].num) return 1;
			else if(c[1][i].num<c[2][i].num) return -1;
		}
		return c[1][5].col<c[2][5].col?1:-1;
	}
	if(k==8 || k==4 || k==7) return c[1][3].num>c[2][3].num?1:-1;
	if(k==2){
		int p1,p2;
		int pos1,pos2;
		for(int i=2;i<=5;i++) if(c[1][i].num==c[1][i-1].num) p1=c[1][i].num,pos1=i;
		for(int i=2;i<=5;i++) if(c[2][i].num==c[2][i-1].num) p2=c[2][i].num,pos2=i;
		if(p1==p2){
			int to1=5,to2=5;
			while(to1 && to2){
				while(c[1][to1].num==p1) to1--;
				while(c[2][to2].num==p2) to2--;
				if(c[1][to1].num==c[2][to2].num) {to1--,to2--;continue;}
				return c[1][to1].num>c[2][to2].num?1:-1;
			}
			return min(c[1][pos1].col,c[1][pos1-1].col)<min(c[2][pos2].col,c[2][pos2-1].col)?1:-1;
		}
		return p1>p2?1:-1;
	}
	if(k==3){
		int p11=c[1][2].num,p12=c[1][4].num,p21=c[2][2].num,p22=c[2][4].num;
		if(p22==p12){
			if(p11==p21){
				int x,y;
				for(int i=1;i<=5;i++) if(c[1][i].num!=p11 && c[1][i].num!=p12) x=c[1][i].num;
				for(int i=1;i<=5;i++) if(c[2][i].num!=p21 && c[2][i].num!=p22) y=c[2][i].num;
				if(x==y){
					int cmpx=5,cmpy=5;
					int pp1,pp2;
					for(int i=1;i<=5;i++) if(c[1][i].num==p12) cmpx=min(cmpx,c[1][i].col);
					for(int i=1;i<=5;i++) if(c[2][i].num==p22) cmpy=min(cmpy,c[2][i].col);
					return cmpx>cmpy?-1:1; 
				}
				return x>y?1:-1;
			}
			return p11>p21?1:-1;
		}
		return p22<p12?1:-1; 
	}
}
int main(){
	int t;
	cin>>t;
	while(t--){
		for(int i=1;i<=5;i++) {scanf("%d%d",&c[1][i].num,&c[1][i].col);if(c[1][i].num==1) c[1][i].num=14;}
		for(int i=1;i<=5;i++) {scanf("%d%d",&c[2][i].num,&c[2][i].col);if(c[2][i].num==1) c[2][i].num=14;}
		sort(c[1]+1,c[1]+5+1,cmp);sort(c[2]+1,c[2]+5+1,cmp);
		int k1=check(1),k2=check(2);
		if(k1==k2) cpr(k1)==1?puts("Alice"):puts("Mukyu");
		else k1>k2?puts("Alice"):puts("Mukyu");
	}
	return 0;
}

相关标签: 模拟