1044: 炸金花
时间限制: 1 Sec
内存限制: 128 MB
http://acm.xidian.edu.cn/problem.php?id=1044
[ 提交][ 状态][ 讨论版]
题目描述
炸金花是一个风靡全球的扑克游戏,不少人因为这个游戏发了家,而更多的人则输得倾家荡产。为了帮助赌徒们戒掉它,现在决定派你去写一个程序,帮助赌徒们更好的认识这个游戏。
炸金花在这里被简化成这样一个情况:每一个人都会得到随机派发的三张牌(每张牌的点数为整数区间[1,9]中的某个数,点数相同的牌最多只有4张),然后比较大小。
比较大小的方式是这样的:
① 豹子:即三张点数一样的牌,若双方都为豹子,则点数大者为大,豹子大于任何其他情况;
② 顺子:即三张点数连续递增的牌,比如(4,5,6),(1,2,3),若双方都是顺子,点数大者为大,顺子大于对子和单张;
③ 对子:即两张点数一样的牌带一张单牌,比如(1,1,4),(2,2,5),若双方都是对子,则成对的牌点数大者为大,如果那一对也一样,则比较单张的大小,对子大于单张;
④ 单张:即三张牌不是上述的三种。单张的比较大小方式是,先比较点数最大的,再比较点数第二大的,再比较点数第三大的。
需要注意的是一个特殊情况,那就是,2,3,5比大部分牌都小,但是比豹子大。
你的任务是,对于对手的给定的一种情况,告诉赌徒,有多少种情况可以赢对方。(4,5,6及5,4,6这样算一种情况)
输入
有多组输入数据,第一行为一个数字T,代表有T组输入数据 (0<T≤1000)。
接下来为T组数据,每组数据占一行,为3个整数,表示对手的拿牌情况。
输出
对于每组数据,在一行上输出一个整数,表示赢得对手的情况数。
样例输入
2
9 9 9
7 8 9
样例输出
1
9
直接统计即可,后面三种情况都把 顺子 给忘了,WA了好久才想到...
#include <cstdio>
#include <algorithm>
using namespace std;
int T,card[5];
int main() {
scanf("%d",&T);
while(T-->0) {
scanf("%d%d%d",card,card+1,card+2);
sort(card,card+3);
if(card[2]==card[0]) {//豹子
printf("%d\n",9-card[2]+1);//豹子点数更大的+(2,3,5)
}
else if(card[1]==card[0]+1&&card[2]==card[1]+1) {//顺子
printf("%d\n",9+9-card[2]);//豹子+顺子点数更大的
}
else if(card[1]==card[2]) {//对子(较大的两张)
int ans=8+7;//豹子+顺子
ans+=(9-card[1])*8+(9-card[0]-1);//对子
printf("%d\n",ans);
}
else if(card[0]==card[1]) {//对子(较小的两张)
int ans=8+7;//豹子+顺子
ans+=(9-card[1])*8+(9-card[2]);//对子
printf("%d\n",ans);
}
else {
int ans=9+7+9*8;//豹子+顺子+对子
for(int i=9;i>card[2];--i) {//枚举单张最大牌
ans+=i-3;//i-次大==1(即 次大==i-1,次大-最小>1)
for(int j=i-2;j>1;--j) {//i-次大>1
ans+=j-1;
}
}
//最大==card[2]
if(card[2]-card[1]>1) {//card[2]-次大==1(即 次大==card[2]-1)
ans+=card[2]-3;
}
for(int i=card[2]-2;i>card[1];--i) {//枚举单张次大牌,且card[2]-次大>1
ans+=i-1;
}
for(int i=card[1]-(card[2]-card[1]==1?2:1);i>card[0];--i)//枚举单张最小牌
++ans;
if(card[0]==2&&card[1]==3&&card[2]==5) {//(2,3,5)大于豹子
ans-=9;
}
printf("%d\n",ans);
}
}
return 0;
}