A - 掌握魔法の东东||

从瑞神家打牌回来后,东东痛定思痛,决定苦练牌技,终成赌神!
东东有 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 种牌型中,每种牌型的方案数。
(奇异博士表示很伤心)
在这里插入图片描述
在这里插入图片描述
我屈服了。我算了好久的数学排列组合,结果还是栽在了某组数据上,还是用程序设计的思维做吧
输入

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

分析:
采用暴力解决办法,把每种情况列出来,用一个结构体数组
因为有2个数是确定的,所以我们只需要将后面3个数组合就可以了
故应该循环3次,应为组合过程会有重复,所以还要除以A33,就是那个
高中数学学过的,如有重复,此题除以3*2*1,如果后面需要4个数,就要
除以4*3*2*1,OK!

代码

#include<iostream>
#include<algorithm>
using namespace std;
struct card{
 int v,c;
 bool operator<(card &p){//比较方法,按照牌面值由小到大排列,如果牌面值相等,就按照花色 
  return v!=p.v ? v<p.v : c<p.c;
 }
 bool operator==(card &cad){//可以删掉,除非你判断两个结构体数组某个元素 
  if(v==cad.v&&c==cad.c)
   return true;
  return false;
 }
};
int a,b,x,y,xx,yy,op[10]={0};
card ca[6];card pok[110];
bool sit2(){//炸弹 
 if(ca[1].v==ca[2].v&&ca[2].v==ca[3].v&&ca[3].v==ca[4].v)
  return true;
 else if(ca[2].v==ca[3].v&&ca[3].v==ca[4].v&&ca[4].v==ca[5].v)
  return true;
 else
  return false;
}
bool sit3(){//三带二 
 if(ca[1].v==ca[2].v&&ca[2].v==ca[3].v&&ca[4].v==ca[5].v)
  return true;
 else if(ca[1].v==ca[2].v&&ca[3].v==ca[4].v&&ca[4].v==ca[5].v)
  return true;
 else
  return false;
}
bool sit4(){//同花 
 for(int mi=1;mi<5;mi++)
  if(ca[mi].c != ca[mi+1].c)
   return false;
 return true;
}
bool sit5(){//顺子 
 for(int mi=2;mi<6;mi++)
  if(ca[mi].v-ca[mi-1].v != 1)
   return false;
 return true;
}
bool sit1(){//同花顺 
 if(sit4() && sit5())
  return true;
 return false;
}
bool sit6(){//三条 
 if(ca[1].v==ca[2].v&&ca[2].v==ca[3].v)
  return true;
 else if(ca[3].v==ca[4].v&&ca[4].v==ca[5].v)
  return true;
 else if(ca[2].v==ca[3].v&&ca[3].v==ca[4].v)
  return true;
 else
  return false;
}
bool sit7(){//两对 
 if(ca[1].v==ca[2].v&&ca[3].v==ca[4].v)
  return true;
 else if(ca[1].v==ca[2].v&&ca[4].v==ca[5].v)
  return true;
 else if(ca[2].v==ca[3].v&&ca[4].v==ca[5].v)
  return true;
 else
  return false;
}
bool sit8(){//一对 
 if(ca[1].v==ca[2].v||ca[2].v==ca[3].v||ca[3].v==ca[4].v||ca[4].v==ca[5].v)
  return true;
 else
  return false;
}
void poke(){
 sort(ca+1,ca+6);
 if(sit1()) op[1]++;
 else if(sit2()) op[2]++;
 else if(sit3()) op[3]++;
 else if(sit4()) op[4]++;
 else if(sit5()) op[5]++;
 else if(sit6()) op[6]++;
 else if(sit7()) op[7]++;
 else if(sit8()) op[8]++;
 else op[9]++;
 
}
int main(){
 ios::sync_with_stdio(false);
 cin>>a>>b;
 cin>>x>>y>>xx>>yy;
 int tag=1;
 ca[1].v=x;ca[1].c=y;
 ca[2].v=xx;ca[2].c=yy;
 for(int i=0;i<a;i++){//把所有不是输入的那两个数存到pok数组中 
  for(int j=0;j<b;j++){
   if(!(ca[1].v==i&&ca[1].c==j)&&!(ca[2].v==i&&ca[2].c==j))
   {
    pok[tag].v=i;pok[tag].c=j;
    tag++;
   } 
  }
 }
/* for(int i=1;i<tag;i++)//自己设置输出看看pok数组对不对 
  cout<<pok[i].v<<"***"<<pok[i].c<<endl;*/
 for(int i=1;i<tag;i++){//传说中的三次循环,分别进行组合 
  for(int j=1;j<tag;j++){
   for(int k=1;k<tag;k++){
    if(i==j||i==k||j==k)
     continue;
    else{
     ca[1].v=x;ca[1].c=y;
     ca[2].v=xx;ca[2].c=yy;
     ca[3]=pok[i];
     ca[4]=pok[j];
     ca[5]=pok[k];
     poke();
    }
   }
  }
 }//组合完了会有重复,比如4 5 6和5 4 6是一回事 
 for(int i=1 ;i<10 ;i++){
  cout<<op[i]/6<<" ";
  if(i==9) cout<<endl;
 }
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值