题目描述
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
Input
25 4
0 0 24 3
Output
0 0 0 2 18 1656 644 36432 113344
思路分析
这其实是一个子集枚举问题,在两个元素已经确定的情况下,枚举所有元素个数为5的子集,并判断类型。Dfs+可行性剪枝。
结构体card存储牌的大小和花色,排序方式为先按大小升序,再按花色升序。结构体数组p存放被选中的五张牌,先判断是否是1、2、3种类型并返回对应值。否则,剩下的几种类型主要是相等的牌数不同,定义整型变量num表示五张牌中不同数字的个数,初值为5;tag为当前已经连续相等的牌数,初值为1(若比较的两张牌不等则重置为1;max为五张牌中最大连续相等的牌数(if(tag>max)max=tag)。
if(num==5) 全不相等
if(num==4) 一对
if(num==3&&max==2)两对
if(num==3&&max==3)三条
if(num==2&&max==4)炸弹
if(num==2&&max==3)三代二
AC代码
#include<iostream>
#include<algorithm>
using namespace std;
int A,B,a1,b1,a2,b2;
int chose[10]={0};//
struct card
{
int a,b;
card(){};
bool operator<(const card &c) const
{//先按大小升序,再按花色升序
if(a!=c.a) return a<c.a;
else
return b<c.b;
}
};
card c[100];//最多一百张牌
card p[5];//五张被选中的牌
void judge(card p[])
{
/*for(int i=0;i<5;i++)
{
cout<<"pai"<<p[i].a<<" "<<p[i].b<<endl;
}*/
bool same=true;
for(int i=0;i<4;i++)
{
if(p[i].b!=p[i+1].b)
{
same=false;
break;
}
}
bool add=true;
for(int i=0;i<4;i++)
{
if((p[i].a+1)!=p[i+1].a)
{
add=false;
break;
}
}
if(same==true&&add==true)
{
chose[1]++;
return;
}
if(same)
{
chose[3]++;
return;
}
if(add)
{
chose[2]++;
return;
}
int num=5;//5张牌中的不同数字 数
int max=1,tag=1;
for(int i=0;i<4;i++)
{
if(p[i].a==p[i+1].a)
{
tag++;
num--;
if(tag>max) max=tag;
}
else{
tag=1;
}
}
if(num==5)
{
chose[9]++;
}//全部不相等
if(num==4)
{
chose[8]++;
}//有一对相等
if(num==3&&max==2)
{
chose[6]++;
}
if(num==3&&max==3)
{
chose[7]++;
}
if(num==2&&max==4)
{
chose[4]++;
}
if(num==2&&max==3)
{
chose[5]++;
}
}
void dfs(int count,int tag)
{
//cout<<"count "<<count<<endl;
if(count==5)
{
card p1[5];
for(int i=0;i<5;i++)
{
p1[i].a=p[i].a;
p1[i].b=p[i].b;
}
sort(p1,p1+5);//排序
judge(p1);
return;
}
for(int i=tag;i<A*B;i++)
{
if((c[i].a==a1&&c[i].b==b1)||(c[i].a==a2&&c[i].b==b2)) continue;
p[count].a=c[i].a;
p[count].b=c[i].b;
//cout<<"第"<<count+1<<"张牌"<<c[i].a<<" "<<c[i].b<<endl;
dfs(count+1,i+1);
}
}
int main()
{
cin>>A>>B;
cin>>a1>>b1>>a2>>b2;
int index=0;
for(int i=0;i<A;i++)
{
for(int j=0;j<B;j++)
{
c[index].a=i;
c[index].b=j;
index++;
}
}
int count=2;//初始牌数等于2
p[0].a=a1;p[0].b=b1;
p[1].a=a2;p[1].b=b2;
dfs(count,0);
for(int i=1;i<=9;i++)
{
cout<<chose[i]<<" ";
}
return 0;
}