【小模拟】掌握魔法の东东 II

问题描述

从瑞神家打牌回来后,东东痛定思痛,决定苦练牌技,终成赌神!
东东有 A × B 张扑克牌。每张扑克牌有一个大小(整数,记为a,范围区间是 0 到 A - 1)和一个花色(整数,记为b,范围区间是 0 到 B - 1。
扑克牌是互异的,也就是独一无二的,也就是说没有两张牌大小和花色都相同。
“一手牌”的意思是你手里有5张不同的牌,这 5 张牌没有谁在前谁在后的顺序之分,它们可以形成一个牌型。 我们定义了 9 种牌型,如下是 9 种牌型的规则,我们用“低序号优先”来匹配牌型,即这“一手牌”从上到下满足的第一个牌型规则就是它的“牌型编号”(一个整数,属于1到9):

同花顺: 同时满足规则 5 和规则 4.
炸弹 : 5张牌其中有4张牌的大小相等.
三带二 : 5张牌其中有3张牌的大小相等,且另外2张牌的大小也相等.
同花 : 5张牌都是相同花色的.
顺子 : 5张牌的大小形如 x, x + 1, x + 2, x + 3, x + 4
三条: 5张牌其中有3张牌的大小相等.
两对: 5张牌其中有2张牌的大小相等,且另外3张牌中2张牌的大小相等.
一对: 5张牌其中有2张牌的大小相等.
要不起: 这手牌不满足上述的牌型中任意一个.

现在, 东东从A × B 张扑克牌中拿走了 2 张牌!分别是 (a1, b1) 和 (a2, b2). (其中a表示大小,b表示花色)

现在要从剩下的扑克牌中再随机拿出 3 张!组成一手牌!!

其实东东除了会打代码,他业余还是一个魔法师,现在他要预言他的未来的可能性,即他将拿到的“一手牌”的可能性,我们用一个“牌型编号(一个整数,属于1到9)”来表示这手牌的牌型,那么他的未来有 9 种可能,但每种可能的方案数不一样。

现在,东东的阿戈摩托之眼没了,你需要帮他算一算 9 种牌型中,每种牌型的方案数。

Input&Output

Input
第 1 行包含了整数 A 和 B (5 ≤ A ≤ 25, 1 ≤ B ≤ 4).
第 2 行包含了整数 a1, b1, a2, b2 (0 ≤ a1, a2 ≤ A - 1, 0 ≤ b1, b2 ≤ B - 1, (a1, b1) ≠ (a2, b2)).
Output
输出一行,这行有 9 个整数,每个整数代表了 9 种牌型的方案数(按牌型编号从小到大的顺序)

Examples

Input

5 2
1 0 3 1

Output

0 0 0 0 8 0 12 36 0

Input

25 4
0 0 24 3

Output

0 2 18 0 0 644 1656 36432 113344

题解

首先枚举牌型,三重循环,升序且不重复。由于a,b不大,判断不重复升序的方法是比较记录a*10+b,等价于先按a的大小排序,再按b的大小排序。
对枚举好的数组进行排序,进行ifelse的牌型判断:
1.同花顺:判断4&5是否为真。
2.炸弹:统计最大数目,若大于等于4,为真。
3.三带二:统计最大和次大数目,若最大为3,次大为2,为真。
4.同花:统计颜色是否相同,相同为真。
5.顺子:循环判断[i]==[i-1]+1?,都为真则结果真。
6.三条:最大数目为3(不可能出现>3的情况)。
7.两对子:最大为2,次大为2。
8.对子:最大为2。
9.要不起:以上全不满足。

Tips

注!意!细!节!!!

变量名就不能取得简单一点吗?a[i].a a[i].b是要闹哪样!!!x[i].a x[i].b这种好看又好记的不香吗!
局部变量累加器memset清零考古级的老错误了!全局变量用久了这都忘了吗!!!

注意全局变量的变动问题。在枚举时间内,其他函数对于枚举序列只有只读权限,否则会改的乱七八糟。

代码


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
using namespace std;
#define rep(i,s,t) for(i=s;i<=t;i++)
#define repi(i,s,t) for(int i=s;i<=t;i++)
#define mem(a,s) memset(a,s,sizeof(a))
int A,B,a1,a2,b1,b2;
bool b[300];//A*10+b
struct node{
	int a,b;
	bool operator<(const node&n){
		if(a!=n.a) return a<n.a;
		return b<n.b;
	}
}x[6],xx[6];
int ans[10]={0};
bool f4(){
	bool s=true;
	repi(i,1,5)
		if(i!=1&&xx[i].b!=xx[i-1].b){
			s=false;break;
		}
	return s;
}
bool f5(){
	bool s=true;
	repi(i,1,5)
		if(i!=1&&(xx[i].a!=xx[i-1].a+1)){
			s=false;break;
		}
	return s;
}
bool f1(){
	if(f4()&&f5())return true;
	return false;
}
bool f2(){
	int num[25],maxn=0;
	mem(num,0);
	repi(i,1,5) num[xx[i].a]++;
	repi(i,0,A-1)
		if(num[i]>maxn)maxn=num[i];
	if(maxn>=4) return true;
	return false;
}
bool f3(){
	int num[25],maxn=0,maxnn=0;
	mem(num,0);
	repi(i,1,5) num[xx[i].a]++;

	repi(i,0,A-1)
		if(num[i]>maxn) maxnn=maxn,maxn=num[i];
		else if(num[i]>maxnn) maxnn=num[i];
	if(maxn==3&&maxnn==2) return true;
	return false;
	
}
bool f6(){
	int num[25],maxn=0;
	mem(num,0);
	repi(i,1,5) num[xx[i].a]++;
	repi(i,0,A-1)
		if(num[i]>maxn)maxn=num[i];
	if(maxn==3) return true;
	return false;
}
bool f7(){
	int num[25],maxn=0,maxnn=0;
	mem(num,0);
	repi(i,1,5) num[xx[i].a]++;
	repi(i,0,A-1)
		if(num[i]>maxn) maxnn=maxn,maxn=num[i];
		else if(num[i]>maxnn) maxnn=num[i];
	if(maxn==2&&maxnn==2) return true;
	return false;
}
bool f8(){
	int num[25],maxn=0;
	mem(num,0);
	repi(i,1,5) num[xx[i].a]++;
	repi(i,0,A-1)
		if(num[i]>maxn)maxn=num[i];
	if(maxn==2) return true;
	return false;
}
void f(){
	repi(i,1,5) xx[i].a=x[i].a,xx[i].b=x[i].b;
	sort(xx+1,xx+6);
	if(f1()){ans[1]++;return;}
	if(f2()){ans[2]++;return;}
	if(f3()){ans[3]++;return;}
	if(f4()){ans[4]++;return;}
	if(f5()){ans[5]++;return;}
	if(f6()){ans[6]++;return;}
	if(f7()){ans[7]++;return;}
	if(f8()){ans[8]++;return;}
	ans[9]++;return;
}
int cnt(int index,int color){return index*10+color;} 
int main(){
//	freopen("1.txt","r",stdin);
	cin>>A>>B>>x[1].a>>x[1].b>>x[2].a>>x[2].b; 
	mem(b,false);mem(ans,0);
	b[cnt(x[1].a,x[1].b)]=b[cnt(x[2].a,x[2].b)]=true;
	rep(x[3].a,0,A-1)	
		rep(x[3].b,0,B-1){ 
			if(!b[cnt(x[3].a,x[3].b)]){
				b[cnt(x[3].a,x[3].b)]=true;
				rep(x[4].a,0,A-1)
					rep(x[4].b,0,B-1)
						if(!b[cnt(x[4].a,x[4].b)]&&cnt(x[3].a,x[3].b)<cnt(x[4].a,x[4].b)){
							b[cnt(x[4].a,x[4].b)]=true;
							rep(x[5].a,0,A-1)
								rep(x[5].b,0,B-1)
									if(!b[cnt(x[5].a,x[5].b)]&&cnt(x[4].a,x[4].b)<cnt(x[5].a,x[5].b)){
										b[cnt(x[5].a,x[5].b)]=true;
										f();					
										b[cnt(x[5].a,x[5].b)]=false;							
									} 	
							b[cnt(x[4].a,x[4].b)]=false;
					} 
				b[cnt(x[3].a,x[3].b)]=false;
			}
		} 
	repi(i,1,9)
		cout<<ans[i]<<' ';
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值