2018.11.01【NOIP训练】梭哈(模拟)

传送门


解析:

本来可以一次ACACAC的。。。结果告诉我A作为顺子其实可以分别作最大值和最小值???

思路:

没什么技术含量的码农模拟题,练一下代码能力还行。

首先对所有牌按照大小排序,这样方便比较,记住把花色取一下负数方便比较。

判断牌型:

然后先考虑两个顺子的情况,如果没有,就把A设置成最大牌来搞剩下的所有情况就行了。

你可以手打模拟(像我一样),也可以用稍微优雅一点的循环来判断。

比较大小:

先比较牌型,不同再根据牌型的特点来判断。

我将如下的几种情况合并起来判断大小,只考虑三种情况:

1.同花顺,同花,顺子和无对

乍一看这几种似乎并没有太多联系,但是他们的判断都基于一个原则,绝对性的先比点数再比花色。

2.满堂红,四条和三条

由于占重头的牌至少有三张,所以最大的牌肯定不会出现重复,直接比较最大牌就好了。

3.两对和一对

这个只能模拟了,将所有对子全部取出来,按照题意比较即可。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const

inline int getint(){
	re int num;
	re char c;
	while(!isdigit(c=gc()));num=c^48;
	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
	return num;
}

struct CARD{
	int point,col;
	friend bool operator<(cs CARD &a,cs CARD &b){
		if(a.point^b.point)return a.point<b.point;
		else return a.col<b.col;
	}
};

struct players{
	CARD card[5];
	int type;
	void trans(){
		for(int re i=0;i<5;++i)if(card[i].point==1)card[i].point=14;
		sort(card,card+5);
	}
	void init(){
		sort(card,card+5);
		//Straight Flush ...9
		
		bool flag=true;
		for(int re i=0;i+1<5;++i)
		if(card[i].point!=card[i+1].point-1||card[i].col!=card[i+1].col){
			flag=false;
			break;
		}
		if(flag){
			type=9;
			return ;
		}
		
		//Straight ...5
		
		flag=true;
		for(int re i=0;i+1<5;++i)
		if(card[i].point!=card[i+1].point-1){
			flag=false;
			break;
		}
		if(flag){
			type=5;
			return ;
		}
		
		trans();//A作为最大牌 
		
		//Straight Flush ...9
		
		flag=true;
		for(int re i=0;i+1<5;++i)
		if(card[i].point!=card[i+1].point-1||card[i].col!=card[i+1].col){
			flag=false;
			break;
		}
		if(flag){
			type=9;
			return ;
		}
		
		//Four of a Kind ...8
		
		flag=(card[0].point==card[1].point||card[3].point==card[4].point)&&
		card[1].point==card[2].point&&card[2].point==card[3].point;
		if(flag){
			type=8;
			return ;
		}
		
		//Full House ...7
		
		flag=card[0].point==card[1].point&&card[3].point==card[4].point&&
		(card[2].point==card[1].point||card[2].point==card[3].point);
		if(flag){
			type=7;
			return ;
		}
		
		//Flush ...6
		
		flag=true;
		for(int re i=1;i<5;++i)
		if(card[i].col!=card[i-1].col){
			flag=false;
			break;
		}
		if(flag){
			type=6;
			return ;
		}
		
		//Straight ...5
		
		flag=true;
		for(int re i=0;i+1<5;++i)
		if(card[i].point!=card[i+1].point-1){
			flag=false;
			break;
		}
		if(flag){
			type=5;
			return ;
		}
		
		//Three of a Kind ...4
		
		flag=(card[0].point==card[1].point&&card[2].point==card[1].point)||
		(card[3].point==card[4].point&&card[2].point==card[3].point)||
		(card[2].point==card[1].point&&card[2].point==card[3].point);
		if(flag){
			type=4;
			return ;
		}
		
		//Two Pairs ...3
		
		int cnt=0;
		for(int re i=1;i<5;++i){
			if(card[i].point==card[i-1].point)++cnt;
		}
		if(cnt==2){
			type=3;
			return ;
		}
		
		//One Pair ...2
		
		if(cnt==1){
			type=2;
			return ;
		}
		
		//Zilch ...1
		
		type=1;
		
	}
}player[2];

#define alice player[0]
#define mukyu player[1]

inline bool cmp(){
	int type=alice.type;
	if(type==9||type==6||type==5||type==1){//绝对性的从大到小先比点再比花 
		for(int re i=4;~i;--i){
			if(alice.card[i].point^mukyu.card[i].point)
			return alice.card[i].point>mukyu.card[i].point;
		}
		return alice.card[4].col>mukyu.card[4].col;
	}
	if(type==8||type==7||type==4)return alice.card[2].point>mukyu.card[2].point;//三张肯定不会有重复的
	
	//type ...3...2 先比对子再比单 
	vector<CARD> p[2];//pair
	vector<CARD> s[2];//single
	for(int re i=0;i<5;++i){
		for(int re j=0;j<2;++j){
			if(i&&player[j].card[i].point==player[j].card[i-1].point)p[j].push_back(player[j].card[i]);
			else if(i<4&&player[j].card[i].point==player[j].card[i+1].point)p[j].push_back(player[j].card[i]);
			else s[j].push_back(player[j].card[i]);
		}
	}
	if(p[0][p[0].size()-1].point^p[1][p[1].size()-1].point)
	return p[0][p[0].size()-1].point>p[1][p[1].size()-1].point;
	if(p[0][0].point^p[1][0].point)
	return p[0][0].point>p[1][0].point;
	for(int re i=s[0].size()-1;~i;--i){
		if(s[0][i].point^s[1][i].point)return s[0][i].point>s[1][i].point;
	}
	return p[0][p[0].size()-1].col>p[1][p[1].size()-1].col;
}

int T;
signed main(){
	T=getint();
	while(T--){
		for(int re i=0;i<5;++i)alice.card[i].point=getint(),alice.card[i].col=4-getint();
		alice.init();//cerr<<"Alice : "<<alice.type<<endl;
		for(int re i=0;i<5;++i)mukyu.card[i].point=getint(),mukyu.card[i].col=4-getint();
		mukyu.init();//cerr<<"Mukyu : "<<mukyu.type<<endl;
		if(mukyu.type^alice.type){
			puts(alice.type>mukyu.type?"Alice":"Mukyu");
			continue;
		}
		puts(cmp()?"Alice":"Mukyu");
	}
	return 0;
}

转载于:https://www.cnblogs.com/zxyoi/p/10047125.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值