SDU week6大模拟 (掌握魔法的东东(Ⅱ)

题目:
从瑞神家打牌回来后,东东痛定思痛,决定苦练牌技,终成赌神!
东东有 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 种牌型中,每种牌型的方案数

输入:
第 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)).

输出:
输出一行,这行有 9 个整数,每个整数代表了 9 种牌型的方案数(按牌型编号从小到大的顺序)
样例:
样例输入:

5 2
1 0 3 1

样例输出:

0 0 0 0 8 0 12 36 0

样例输入:

25 4
0 0 24 3

样例输出:

0 2 18 0 0 644 1656 36432 113344

分析:
这次题如果数据量大的话,可能就是一场灾难。但是好在数据量小,可以直接暴力求解,因此另一场小灾难来了(因为长时间不敢直接用n3 求解,等问人家可以暴力的时候,惊讶中已经晚了)。所以这次最大的教训就是数据量了,能简单的做出来,绝不用各种复杂的方法。因此本题也是直接暴力枚举出另外3个数,分别判断即可。

总结:
由以上分析就可以看出来,这道题不能说是难但是确实非常的繁琐。就实验过程中的问题分析总结一下:
(1)排序:
假设数组直接排序,那么固定的前两个数的位置就可能改变,结果肯定错误。解决这个问题的方法就是复制构造另外一个相同的数组,判断复制后的数组的情况。
(2)依然是排序可以解决的问题,在题目中很多出现几个相等的情况。排序后相等的位置是可以判断出来的。这样就会方便很多。
代码:

#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
struct p{
	int x,y;  //x 表示数字 ,y表示花色
	bool operator <(const p &e) const {
		return x<=e.x; 
	}
};
int A,B;
p pp[6];   //复制后进行运算的数组 
p ppp[6];
int res[9];
bool checkH()   //检查花色是不是相同 
{
	if(pp[0].y==pp[1].y&&pp[1].y==pp[2].y&&pp[2].y==pp[3].y&&pp[3].y==pp[4].y)
		return true;
	else return false;
}
bool checkL()    //判断是不是连续的 
{
	if(pp[0].x+1==pp[1].x&&pp[1].x+1==pp[2].x&&pp[2].x+1==pp[3].x&&pp[3].x+1==pp[4].x)
		return true;
	else return false;
}	
void judge()
{
	if(checkL()&&checkH())	{
		res[0]++;
		return ;
	}
	else if((pp[0].x==pp[1].x&&pp[1].x==pp[2].x&&pp[2].x==pp[3].x)||
		(pp[3].x==pp[4].x&&pp[1].x==pp[2].x&&pp[2].x==pp[3].x)){
			res[1]++;
			return;
		}
	else if((pp[0].x==pp[1].x&&pp[1].x==pp[2].x&&pp[4].x==pp[3].x)||
		(pp[0].x==pp[1].x&&pp[3].x==pp[2].x&&pp[4].x==pp[3].x)){
			res[2]++;
			return ;
		}
	else if(checkH()){
		res[3]++;
		return ;
	}	
	else if(checkL()){
		res[4]++;
		return ;
	}
	else if((pp[0].x==pp[1].x&&pp[1].x==pp[2].x)||
		(pp[1].x==pp[2].x&&pp[3].x==pp[2].x)||
		(pp[3].x==pp[2].x&&pp[4].x==pp[3].x))
		{
			res[5]++;
			return ;
		}
	else if((pp[0].x==pp[1].x&&pp[3].x==pp[2].x)||
	(pp[0].x==pp[1].x&&pp[3].x==pp[4].x)||
	(pp[2].x==pp[1].x&&pp[3].x==pp[4].x)){
		res[6]++;
		return ;
		}
	else if((pp[0].x==pp[1].x)||(pp[2].x==pp[1].x)||(pp[2].x==pp[3].x)||(pp[3].x==pp[4].x))	{
		res[7]++;
		return ;
	}
	else {
			res[8]++;
			return ;
	}	
}

int main()
{
	scanf("%d%d",&A,&B);
	p p1,p2,p3,p4,p5;
	scanf("%d%d%d%d",&p1.x,&p1.y,&p2.x,&p2.y);
	ppp[0]=p1;
	ppp[1]=p2;
	int x1=p1.x*B+p1.y;
	int x2=p2.x*B+p2.y;
	for(int i=0;i<A*B;i++)
	{
		if(i==x1||i==x2) continue;
		for(int j=i+1;j<A*B;j++)
		{
			if(j==x1||j==x2)	continue;
			for(int k=j+1;k<A*B;k++)
			{
				if(k==x1||k==x2) continue;
				p3.x=i/B;
				p3.y=i%B;
				ppp[2]=p3;
				p4.x=j/B;
				p4.y=j%B;
				ppp[3]=p4;
				p5.x=k/B;
				p5.y=k%B;
				ppp[4]=p5;
				for(int i=0;i<5;i++)
				{
					pp[i]=ppp[i];
				}
				sort(pp,pp+5);   //问题在排序的时候改变了相对位置 
				judge(); 
			} 
		}
	}
	for(int i=0;i<9;i++)
	{
		printf("%d ",res[i]); 
	}
}
发布了10 篇原创文章 · 获赞 0 · 访问量 165

猜你喜欢

转载自blog.csdn.net/weixin_45736432/article/details/105222437
今日推荐