[大模拟]梭哈

描述 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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
一.扑克牌游戏 一副扑克牌去除大小王,剩余52张,A--K,红心,方块,黑桃,梅花四种花色。然后把这一副牌发给两个人,每人分得五张,比较这两人手中牌的大小。 大小的判定规则暂定如下: 牌型比较:同花顺>铁支>葫芦>同花>顺子>三条>二对>对子>散牌。 数字比较:A>K>Q>J>10>9>8 花式比较:黑桃>红桃>草花>方片 牌型说明: 同花顺:拥有五张连续性同花色的顺子。以A为首的同花顺最大。 铁支:四张相同数字的牌,外加一单张。比数字大小,「A」铁支最大 葫芦:由「三条」加一个「对子」所组成的牌,若别家也有此牌型,则比三条数字大小 同花:不构成顺子的五张同花色的牌。先比数字最大的单张,如相同再比第二支、依此类推 顺子:五张连续数字的牌组。 以A为首的顺子最大,如果大家都是顺子,比最大的一张牌,如果大小还一样就比这张牌的花式 三条:牌型由三张相同的牌组成,以A为首的三条最大 二对:牌型中五张牌由两组两张同数字的牌所组成。若遇相同则先比这副牌中最大的一对,如又相同再比第二对,如果还是一样,比大对子中的最大花式 对子:牌型由两张相同的牌加上三张单张所组成。如果大家都是对子,比对子的大小,如果对子也一样,比这个对子中的最大花色 散牌:单一型态的五张散牌所组成,不成对(二对),不成三条,不成顺(同花顺),不成同花,不成葫芦,不成铁支。先比最大一张牌的大小,如果大小一样,比这张牌的花色。
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值