题意
从瑞神家打牌回来后,东东痛定思痛,决定苦练牌技,终成赌神!
东东有 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 种牌型的方案数(按牌型编号从小到大的顺序)
样例:
Input
5 2
1 0 3 1
Output
0 8 0 0 0 12 0 36 0
思路
- 由于数据范围比较小,这个题使用了暴力的方法,接下来就是分析如何暴力
- 首先是得到五张互斥的手牌,这个过程可以通过三重循环去实现,在循环过程中,加入互斥判断条件,使得不会出现相同的牌;
- 紧接着应该思考的一个问题就是如何去判断这五张牌属于哪一种牌,牌的类型有九种;
- 我们可以发现同花,所有牌的颜色相同,那么我们就可以为每一张手牌加一个color_number(花色重复度),初始为1,如果出现花色相同的牌,那么这张牌的color_number+1;通过两次两重循环就可以知道所有的牌的color_number;
- 另一个需要构建的是大小重复复value_number;如果出现相同的,那么就+1;
- 所以存储手牌的是结构体数组,成员为 value,color,value_number(大小重复度),color_number(花色重复度);
- 我们需要额外的三个数组,p1进行value值的<重载,pp进行color_number的<重载,ppp进行value_number的<重载;然后对这三个数组进行升序排序;
- 同花,就是数组pp的最后一个元素的color_number=5;顺子就是p原数组的每一个元素加一都等于下一个元素;同花顺就是pp数组最后一个元素的color_number=5且p原数组的每一个元素加一都等于下一个元素;炸弹就是ppp数组最后一个元素的value_number=4;三代二就是ppp数组最后一个元素的value_number=3且第二个元素的value_number=2;两对就是ppp数组最后一个元素的value_number=2且第二个元素的value_number=2;三条是ppp数组最后一个元素的value_number=3且第二个元素的value_number=1;一对就是ppp数组最后一个元素的value_number=2,且第三个元素value_number=1;要不起就是不满足以上八种;
- 每一个情况都有一个常量值在计数
总结
- 此题就是获得手牌的时候要进行将一些错误的数据排除,就是不能出现互斥,所以使用三重循环,然后三重循环是递进的,下一重循环的起始点是上一重循环的起始点加1,这就能避免三次出现互斥,然后再每次循环都要和第一张和第二张手牌进行互斥判断;
- 其次就是保留原数组,因为前两张牌是一直不变的;
代码
#include<iostream>
#include<algorithm>
using namespace std;
struct card {
int value;
int color;
int value_number;//重复度
int color_number;//重复度
bool operator<(const card& x)
{
return value< x.value;
}
card& operator=(const card& x)
{
value = x.value;
color = x.color;
value_number= x.value_number;
color_number = x.color_number;
return *this;
}
bool operator!=(const card& x)
{
if (value != x.value)
return true;
if (color != x.color)
return true;
return false;
}
};
struct card1 {
int value1;
int color1;
int value_number1;//重复度
int color_number1;//重复度
card1& operator=(const card& x)
{
value1 = x.value;
color1 = x.color;
value_number1 = x.value_number;
color_number1 = x.color_number;
return *this;
}
bool operator<(const card1& x)
{
return color_number1 < x.color_number1;
}
};
struct card2 {
int value2;
int color2;
int value_number2;//重复度
int color_number2;//重复度
card2& operator=(const card& x)
{
value2 = x.value;
color2 = x.color;
value_number2 = x.value_number;
color_number2 = x.color_number;
return *this;
}
bool operator<(const card2& x)
{
return value_number2 < x.value_number2;
}
};
card p[5];
int a[9];
int A=0, B=0;
void calculate()
{
for(int i=0;i<5;i++)
for (int j = 0; j < 5; j++)
{
if (p[i].color == p[j].color)
p[i].color_number++;
if (p[i].value == p[j].value)
p[i].value_number++;
}
}
void init()
{
for (int i = 0; i < 5; i++)
{
p[i].color_number = 0;
p[i].value_number = 0;
}
}
void panduan() //初始化
{
card1 pp[5];//,
card2 ppp[5];
card p1[5];
for (int i = 0; i < 5; i++)
p1[i] = p[i]; //进行value的排序
for (int i = 0; i < 5; i++)
{
pp[i] = p[i]; //进行color重复度的排序
}
for (int i = 0; i < 5; i++)
{
ppp[i] = p[i]; //进行value重复度的排序
}
sort(p1, p1 + 5);
sort(pp, pp+ 5);
sort(ppp, ppp + 5);
if (pp[4].color_number1 == 5 && (p1[0].value + 1 == p1[1].value && p1[1].value + 1 == p1[2].value && p1[2].value + 1 == p1[3].value && p1[3].value + 1 == p1[4].value))
a[0]++;
else if (p1[0].value + 1 == p1[1].value && p1[1].value + 1 == p1[2].value && p1[2].value + 1 == p1[3].value && p1[3].value + 1 == p1[4].value)
a[1]++;
else if (pp[4].color_number1 == 5)
a[2]++;
else if (ppp[4].value_number2 == 4)
a[3]++;//炸弹
else if (ppp[4].value_number2 == 3 && ppp[1].value_number2 == 2)
a[4]++;//三代二
else if (ppp[4].value_number2 == 2 && ppp[1].value_number2 == 2)
a[5]++;//两队
else if (ppp[4].value_number2 == 3 && ppp[1].value_number2 == 1)
a[6]++;//三条
else if (ppp[4].value_number2 == 2 && ppp[2].value_number2 == 1)
a[7]++;//一对;
else
a[8]++;//要不起;
}
void get(int a1,int b1,int a2,int b2)
{
int leng = A * B;
card* m = new card[leng];
int count = 0;
for(int i=0;i<A;i++)
for (int j = 0; j < B; j++)
{
m[count].value = i;
m[count].color = j;
count++;
}
for (int i = 0; i < A * B - 2; i++)
{
if (m[i]!=p[0]&&m[i]!=p[1])
{
for (int j = i+1; j < A * B - 1; j++)
{
if (m[j] != p[0] && m[j] != p[1])
{
for (int k = j+1; k < A * B; k++)
{
if (m[k] != p[0] && m[k] != p[1])
{
p[2] = m[i];
p[3] = m[j];
p[4] = m[k];
init();
calculate();
panduan();
}
}
}
}
}
}
}
int main()
{
cin >> A >> B;
int a1, b1, a2, b2;
cin >> a1 >> b1 >> a2 >> b2;
p[0].value = a1;
p[0].color = b1;
p[1].value = a2;
p[1].color = b2;
get(a1,b1,a2,b2);
for (int i = 0; i < 9; i++)
cout << a[i] << " ";
return 0;
}