掌握魔法の东东 II
题意:
从瑞神家打牌回来后,东东痛定思痛,决定苦练牌技,终成赌神!
东东有 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 种牌型中,每种牌型的方案数。
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 种牌型的方案数(按牌型编号从小到大的顺序)
Examples
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
我的题解:
本题是一道模拟题,模拟每种情况并判断属于哪种牌。
但是我做成了一道组合题。。。
对于给定的牌,我们很容易根据已知的两张得到另外的三张牌的可能结果,然后枚举判断。
我的思路是根据组合公式计算具体每种牌的数目。具体计算的时候要注意同花、顺子、同花顺这些的区别和联系,要去重!!
1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 int A,B,a1,b1,a2,b2; 5 long long sign=0; 6 //typedef struct node{ 7 // int num; //A 8 // int color; //B 9 //} card; 10 /*5 2 11 0 1 1 1 12 1 0 0 1 7 0 12 36 -1 13 */ 14 long long zuhe(int n,int m){ 15 long long res = 1; 16 for(int i=0;i<m;i++) 17 res = res*(n-i)/(i+1); 18 return res; 19 } 20 //1、同花顺 21 long long THS(){ 22 long long result=0; 23 if(b1==b2) 24 { 25 int cha = a1-a2; 26 if(cha==4) 27 result += 1; 28 else if(cha==3) { 29 if(a1+1 <= A) 30 result += 1; 31 if(a2-1 >= 1) 32 result += 1; 33 } 34 else if(cha==2){ 35 //result += B* 36 if(a1+2 <= A ) 37 result += 1; 38 if(a2-1 >= 1 && a1+1<=A) 39 result += 1; 40 if(a2-2 >= 1) 41 result += 1; 42 } 43 else if(cha==1){ 44 if(a2-3>=1 ) 45 result += 1; 46 if(a2-2>=1 && a1+1<=A) 47 result += 1; 48 if(a2-1>=1 && a1+2<=A) 49 result += 1; 50 if( a1+3<=A) 51 result += 1; 52 } 53 } 54 sign += result; 55 return result; 56 } 57 //2炸弹 58 long long ZD(){ 59 long long result = 0; 60 if(B>=4) 61 { 62 if(a1==a2 ){ 63 result+=zuhe(B-2,2)*zuhe(A-1,1)*B; 64 } 65 else{ 66 result += 2*zuhe(B-1,3); 67 } 68 } 69 sign += result; 70 return result; 71 } 72 //3 三带二 73 long TW(){ 74 long long result = 0; 75 if(B>=3){ 76 if(a1==a2){ 77 //两种方案 78 result += zuhe(A-1,1)*zuhe(B,3);//3+2 79 result += zuhe(B-2,1)*zuhe(A-1,1)*zuhe(B,2);//2+3 80 } 81 else { 82 //两种方案数相等 83 result += 2*zuhe(B-1,2)*zuhe(B-1,1); 84 } 85 } 86 sign += result; 87 return result; 88 } 89 //4同花 错了!!! 90 long TH(){ 91 long long result = 0; 92 if(b1==b2){ 93 result += zuhe(A-2,3); 94 //去掉相连的情况 95 int cha = a1-a2; 96 if(cha==4) 97 result -= 1; 98 else if(cha==3) { 99 if(a1+1 <= A) 100 result -= 1; 101 if(a2-1 >= 1) 102 result -= 1; 103 } 104 else if(cha==2){ 105 //result += B* 106 if(a1+2 <= A ) 107 result -= 1; 108 if(a2-1 >= 1 && a1+1<=A) 109 result -= 1; 110 if(a2-2 >= 1) 111 result -= 1; 112 } 113 else if(cha==1){ 114 if(a2-3>=1 ) 115 result -= 1; 116 if(a2-2>=1 && a1+1<=A) 117 result -= 1; 118 if(a2-1>=1 && a1+2<=A) 119 result -= 1; 120 if( a1+3<=A) 121 result -= 1; 122 } 123 } 124 sign+= result; 125 return result; 126 } 127 //5顺子 128 long long SZ(){ 129 long long result = 0; 130 int cha = a1-a2; 131 long long w =(long long)pow(B,3); 132 if(b1==b2) 133 w-=1; 134 if(cha==4) 135 result += w; 136 else if(cha==3) { 137 if(a1+1 <= A) 138 result += w; 139 if(a2-1 >= 1) 140 result += w; 141 } 142 else if(cha==2){ 143 //result += B* 144 if(a1+2 <= A ) 145 result += w; 146 if(a2-1 >= 1 && a1+1<=A) 147 result += w; 148 if(a2-2 >= 1) 149 result += w; 150 } 151 else if(cha==1){ 152 if(a2-3>=1) 153 result +=w; 154 if(a2-2>=1 && a1+1<=A) 155 result += w; 156 if(a2-1>=1 && a1+2<=A) 157 result += w; 158 if(a1+3<=A) 159 result += w; 160 } 161 sign +=result; 162 return result; 163 } 164 //6 三条 165 long long TT(){ 166 long long result = 0; 167 if(B>=3){ 168 if(a1==a2){ 169 result += zuhe(B-2,1)*zuhe(A-1,2)*B*B*2; 170 } 171 else { //3 1 1 1 3 1 172 result += 2 * zuhe(B-1,2)*zuhe(A-2,1)*B; 173 //a b 1 1 3 174 result += zuhe(A-2,1)*zuhe(B,3); 175 } 176 } 177 sign += result; 178 return result; 179 } 180 //7两对 181 long long Tw(){ 182 long long result = 0; 183 //2+2+1 2 1 2 184 if(B>=2){ 185 if(a1==a2) 186 result += zuhe(A-1,1)*zuhe(B,2)*zuhe(A-2,1)*B; 187 //result += zuhe(A-1,2)*2*zuhe(B,2)*B; 188 else 189 { 190 result += zuhe(B-1,1)*zuhe(B-1,1)*zuhe((A-2)*B,1); 191 result += 2*zuhe(B-1,1)*zuhe(A-2,1)*zuhe(B,2); 192 } 193 } 194 sign +=result; 195 return result; 196 } 197 //8一对 198 long long OD(){ 199 long long result = 0; 200 if(B>=2){ 201 if(a1==a2) //选三个大小不相等的 202 result += (A-1)*B*(A-2)*B*(A-3)*B; 203 else //已知不等,选3个使得两个相等 204 { // 1 1 ==> 1 1 1 2 205 /// result += 2*zuhe(B-1,1)*zuhe(A-2,2)*B*B; 206 result += (B-1)*(A-2)*B*(A-3)*B; 207 // result += zuhe(A-2,1)*B*zuhe(A-3,1)*zuhe(B,2); 208 result += (A-2)*B*(A-3)*zuhe(B,2); 209 //result += zuhe(A-2,2)*2*zuhe(B,2)*B; 210 //result += zuhe(A-2,2)*B*B*4*(B-1); 211 } 212 } 213 sign += result; 214 return result; 215 } 216 long long ybq(){ 217 long long result = zuhe(A*B-2,3)-sign; 218 //cout<<result<<endl; 219 return result; 220 } 221 int main(){ 222 cin>>A>>B; 223 cin>>a1>>b1>>a2>>b2; 224 a1+=1;a2+=1; 225 int cha=a1-a2; 226 if(cha<0){ 227 a1^=a2;a2^=a1;a1^=a2; 228 b1^=b2;b2^=b1;b1^=b2; 229 } 230 //九种方案 231 cout<<THS()<<" "<<ZD()<<" "<<TW()<<" "<<TH() 232 <<" "<<SZ()<<" "<<TT()<<" "<<Tw()<<" "<<OD()<<" "; 233 cout<<ybq()<<endl; 234 //cout<<zuhe(3,3)<<endl; 235 //cout<<sign<<endl; 236 sign=0; 237 return 0; 238 }