A - 掌握魔法の东东 II

A - 掌握魔法の东东 II

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

同花顺: 同时满足规则 2 和规则 3.
顺子 : 5张牌的大小形如 x, x + 1, x + 2, x + 3, x + 4
同花 : 5张牌都是相同花色的.
炸弹 : 5张牌其中有4张牌的大小相等.
三带二 : 5张牌其中有3张牌的大小相等,且另外2张牌的大小也相等.
两对: 5张牌其中有2张牌的大小相等,且另外3张牌中2张牌的大小相等.
三条: 5张牌其中有3张牌的大小相等.
一对: 5张牌其中有2张牌的大小相等.
要不起: 这手牌不满足上述的牌型中任意一个.
现在, 东东从A × B 张扑克牌中拿走了 2 张牌!分别是 (a1, b1) 和 (a2, b2). (其中a表示大小,b表示花色)
现在要从剩下的扑克牌中再随机拿出 3 张!组成一手牌!!
其实东东除了会打代码,他业余还是一个魔法师,现在他要预言他的未来的可能性,即他将拿到的“一手牌”的可能性,我们用一个“牌型编号(一个整数,属于1到9)”来表示这手牌的牌型,那么他的未来有 9 种可能,但每种可能的方案数不一样。
现在,东东的阿戈摩托之眼没了,你需要帮他算一算 9 种牌型中,每种牌型的方案数。

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 8 0 0 0 12 0 36 0
Input
25 4
0 0 24 3
Output
0 0 0 2 18 1656 644 36432 113344

思路:这道题看上去题量比较大,类似于分类一样,将所有可能的情况一一计算,一开始做的时候没看清每种牌只属于后这些类别的一种,所以做的时候考虑的复杂了一些,在得知这些后,我选择的是排列组合的做法,这可能没什么算法可言,但是从上到下,所有情况都是清楚的,我们可以计算出每种情况的种类,详细可以看代码。

#include <iostream>

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

using namespace std;

int cb(int m,int n)//自定义组合数C(m,n)
{
	if(n==0)
	{
		return 1;
	}
	int ans=1;
	int chushu=1;
	for(int i=m;i>m-n;i--)
	{
		ans=ans*i;
	}
	for(int i=1;i<=n;i++)
	{
		chushu=chushu*i;
	}
	ans=ans/chushu;
	return ans;
}

int main()
{
	int A,B;
	cin>>A;
	cin>>B;
	int a1,b1,a2,b2;//a代表数字,b代表花色
	cin>>a1;
	cin>>b1;
	cin>>a2;
	cin>>b2;
	if(a1>a2)//保证a1为较小的
	{
		swap(a1,a2);
		swap(b1,b2);
	}
	int sum[10];//记录各个情况的数量
	for(int i=0;i<10;i++)
	{
		sum[i]=0;
	 }
	int all=cb(A*B-2,3);//所有情况 
	bool tonghua=false;
	if(b1==b2&&a2-a1<5)//同花顺 
	{
		if(a2-a1==4)
		{
			sum[1]=1;
		}
		else if(a2-a1==3)
		{ 
			if(A==5)
			{
				sum[1]=1;
			}
			else
			{
				if(a1==0||a2==A-1)//不为第一个或最后一个数 
				{
					sum[1]=1;
				}
				else
				{
					sum[1]=2; 	
				}
			}
		}
		else if(a2-a1==2)
		{
			if(A==5)
			{
				sum[1]=1;
			}
			else if(A==6)
			{
				if(a1==0||a2==A-1)
				{
					sum[1]=1;
				}
				else
				{
					sum[1]=2;
				}
			}
			else
			{
				if(a1==0||a2==A-1)
				{
					sum[1]=1;
				}
				else if(a1==1||a2==A-2)
				{
					sum[1]=2;
				}
				else
				{
					sum[1]=3;
				}
			}
		}
		else if(a2-a1==1)
		{
			if(A==5)
			{
				sum[1]=1;
			}
			else if(A==6)
			{
				if(a1==0||a2==A-1)
				{
					sum[1]=1;
				}
				else
				{
			    	sum[1]=2;	
				}				
				
			}
			else if(A==7)
			{
				if(a1==0||a2==A-1)
				{
					sum[1]=1;
				}
				else if(a1==1||a2==A-2)
				{
					sum[1]=2;
				}
				else
				{
					sum[1]=3;
				}				
			}
			else
			{
				if(a1==0||a2==A-1)
				{
					sum[1]=1;
				}
				else if(a1==1||a2==A-2)
				{
					sum[1]=2;
				}
				else if(a1==2||a2==A-3)
				{
					sum[1]=3;
				}
				else
				{
					sum[1]=4;
				}
			}			
		}
	}
	
		if(b1!=b2)//花色不同 
		{
			sum[1]=0;
			sum[3]=0; 
		}
		else
		{
			sum[3]=cb(A-2,3)-sum[1];
		}
		if(a2-a1>=5)
		{
			sum[1]=0;
			sum[2]=0;
		}
		else
		{
			if(a2-a1==4)
			{
				sum[2]=B*B*B-sum[1];
			}
			else if(a2-a1==3)
			{
				if(A==5)
				{
					sum[2]=B*B*B-sum[1];
				}
				else
				{
					if(a1==0||a2==A-1)
					{
						sum[2]=B*B*B-sum[1];
					}
					else
					{
						sum[2]=B*B*B*2-sum[1];					
					}
				}
			}
			else if(a2-a1==2)
			{
				if(A==5)
				{
					sum[2]=B*B*B-sum[1];
				}
				else if(A==6)
				{
					if(a1==0||a2==A-1)
					{
						sum[2]=B*B*B-sum[1];
					}
					else
					{
						sum[2]=B*B*B*2-sum[1];					
					}
				}
				else
				{
					if(a1==0||a2==A-1)
					{
						sum[2]=B*B*B-sum[1];
					}
					else if(a1==1||a2==A-2)
					{
						sum[2]=B*B*B*2-sum[1];					
					}	
					else
					{
						sum[2]=B*B*B*3-sum[1];
					}				
				}
			}
			else if(a2-a1==1)
			{
				if(A==5)
				{
					sum[2]=B*B*B-sum[1];
				}
				else if(A==6)
				{
					if(a1==0||a2==A-1)
					{
						sum[2]=B*B*B-sum[1];
					}
					else
					{
						sum[2]=B*B*B*2-sum[1];					
					}
				}
				else if(A==7)
				{
					if(a1==0||a2==A-1)
					{
						sum[2]=B*B*B-sum[1];
					}
					else if(a1==1||a2==A-2)
					{
						sum[2]=B*B*B*2-sum[1];					
					}	
					else
					{
						sum[2]=B*B*B*3-sum[1];
					}
				}
				else
				{
					if(a1==0||a2==A-1)
					{
						sum[2]=B*B*B-sum[1];
					}
					else if(a1==1||a2==A-2)
					{
						sum[2]=B*B*B*2-sum[1];					
					}	
					else if(a1==2||a2==A-3)
					{
						sum[2]=B*B*B*3-sum[1];
					}
					else
					{
						sum[2]=B*B*B*4-sum[1];	
					}
				}
			}
		}
	
	//炸弹4
	if(B==4)
	{
		if(a1==a2)
		{
			sum[4]=A*B-4;
		}
		else
		{
			sum[4]=2; 
		}
	 }
	if(B>=3)//三带二5,三条7
	{
		if(a1==a2)
		{
			sum[5]=(B-2)*(A-1)*cb(B,2)+(A-1)*cb(B,3);
			sum[7]=(B-2)*cb(A-1,2)*B*B;
		}
		else
		{
			sum[5]=2*cb(B-1,2)*cb(B-1,1);
			sum[7]=2*cb(B-1,2)*(A-2)*B+(A-2)*cb(B,3);
		}
	}
	if(B>=2)//两对6 一对8
	{
		if(a1==a2)
		{
			sum[6]=(A-1)*cb(B,2)*(A-2)*B;
			sum[8]=cb(A-1,3)*B*B*B;
		}
		else
		{
			sum[6]=(B-1)*(B-1)*(A-2)*B+2*(B-1)*(A-2)*cb(B,2);
			sum[8]=2*(B-1)*cb(A-2,2)*B*B+(A-2)*B*(A-3)*cb(B,2);
		}
	}
	sum[9]=all-sum[1]-sum[2]-sum[3]-sum[4]-sum[5]-sum[6]-sum[7]-sum[8];
	for(int i=1;i<=9;i++)
	{
		cout<<sum[i]<<' ';
	}
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值