Week6 限时大模拟 掌握魔法の东东 II Gym

题目描述:

东东 has A × B cards. Each card has a rank, an integer between 0 and A - 1, and a suit, an integer between 0 and B - 1. All cards are distinct. A set of five different cards is known as a hand. Each hand is in exactly one of nine categories numbered from 1 to 9. If a hand satisfies the conditions for membership in multiple categories, it is considered to be in the lowest-numbered such category. The rules for each category are:

  1. Straight flush: is a Straight and a Flush.
  2. Four of a kind: four of the cards have the same rank.
  3. Full house: three of the cards have the same rank and the remaining two have the same rank.
  4. Flush: all five cards have the same suit.
  5. Straight: the ranks of the cards in increasing order are xx + 1, x + 2, x + 3, x + 4 for some integer x.
  6. Three of a kind: three of the cards have the same rank.
  7. Two pair: two cards have the same rank and two other cards have the same rank.
  8. One pair: two cards have the same rank.
  9. High card: if a hand does not satisfy any other category.

Currently, 东东 has two cards with ranks a1, a2 and suits b1, b2. Of the remaining cards, Vera will choose three more cards and form a hand with her two current cards. Compute the number of different hands formed in this way that belong in each category.

值得注意的是,“一手牌”从上到下满足的第一个牌型规则就是它的“牌型编号”

思路:

暴力枚举所有可能的牌型,对这手牌进行判断即可。

主要矛盾是如何判断:可以发现,花色只在判断同花的时候才有用,所以花色和数值可以不用捆在一起。

我的实现方法(只关注牌的数值):对5张牌大小排序,统计5张中,相同的牌最多几个,设其为max,再判断是否有对子(三条也是有对子),设其标志为isP;把5张牌放入集合S(集合元素互异)。

现在有三个参数:max,isP,S.size() 。这三个参数综合,能区分三条、对子、两个对子、三带二、炸弹。

代码:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <vector>
 4 #include <algorithm>
 5 #include <set>
 6 #include <cstring>
 7 using namespace std;
 8 int A,B;
 9 int num[500],color[500]; 
10 int kind[100];
11 int status[100];    //status是对每一手牌来说的 
12 vector< pair<int,int> > v;  //数字 花色
13 int a1,b1,a2,b2;
14 pair<int,int> t1,t2;
15 int maxi,lmaxi;  //lmaxi 判断是否有对子 lmaxi==2表示有对子 
16 int cnt()   //判断这五个牌有几个大小相等 
17 {
18     sort(num+1,num+5+1);
19     //sort(color+1,color+5+1);
20     maxi=-1;
21     for(int i=1;i<=5;i++)
22     {
23         int k1=count(num+1,num+5+1,num[i]);
24         maxi=max(k1,maxi);
25         if(k1==2) lmaxi=2;
26     }     
27     return maxi;     
28 }
29 void func()
30 {
31     set<int> S={num[1],num[2],num[3],num[4],num[5]};
32     int k1=count(color+1,color+5+1,color[1]);
33     if(k1==5) status[4]=1;
34     if(num[2]==num[1]+1&&num[3]==num[2]+1&&num[4]==num[3]+1&&num[5]==num[4]+1)
35         status[5]=1;
36     if(status[4] && status[5] ) kind[1]++,status[1]=1;
37     if(maxi==4) kind[2]++,status[2]=1;
38     if(maxi==3 && lmaxi==2 && S.size()==2) kind[3]++,status[3]=1;
39     if(status[4]==1 && status[1]==0) kind[4]++;
40     if(status[5]==1 && status[1]==0) kind[5]++;
41     if(maxi==3&& status[3]==0) kind[6]++,status[6]=1;
42     if(maxi==2&&S.size()==3) kind[7]++,status[7]=1;
43     if(maxi==2&&S.size()==4) kind[8]++,status[8]=1;
44     if( count(status+1,status+8+1,0)==8 ) kind[9]++;
45 }
46 int main()
47 {
48     cin>>A>>B;
49     cin>>a1>>b1>>a2>>b2;
50     t1={a1,b1},t2={a2,b2};
51     for(int i=0;i<A;i++)
52         for(int j=0;j<B;j++)
53         {
54             pair<int,int> p={i,j};
55             if( p!=t1 && p!= t2)
56                 v.push_back(p);
57         }
58     int n=v.size();
59     for(int i=0;i<n;i++)
60         for(int j=i+1;j<n;j++)
61             for(int k=j+1;k<n;k++)
62             {
63                 memset(status,0,sizeof(status) );
64                 num[1]=a1,num[2]=a2; 
65                 color[1]=b1,color[2]=b2;
66                 num[3]=v[i].first; color[3]=v[i].second;
67                 num[4]=v[j].first; color[4]=v[j].second;
68                 num[5]=v[k].first; color[5]=v[k].second;
69                 cnt();
70                 func();
71             }
72     for(int i=1;i<=9;i++)
73      cout<<kind[i]<<' ';
74 }
原文地址:https://www.cnblogs.com/qingoba/p/12620518.html