题目描述:
达达学会了使用扑克DIY占卜。方法如下:
一副去掉大小王的扑克共52张,打乱后均分为13堆,编号1~13,每堆4张,其中第13堆称作“生命牌”,也就是说你有4条命。这里边,4张K被称作死神。初始状态下,所有的牌背面朝上扣下。
流程如下:
1.抽取生命牌中的最上面一张(第一张)。
2.把这张牌翻开,正面朝上,放到牌上的数字所对应编号的堆的最上边。(例如抽到2,正面朝上放到第2堆牌最上面,又比如抽到J,放到第11堆牌最上边,注意是正面朝上放)
3.从刚放了牌的那一堆最底下(最后一张)抽取一张牌,重复第2步。(例如你上次抽了2,放到了第二堆顶部,现在抽第二堆最后一张发现是8,又放到第8堆顶部.........)
4.在抽牌过程中如果抽到K,则称死了一条命,就扔掉K再从第1步开始。
5.当发现四条命都死了以后,统计现在每堆牌上边正面朝上的牌的数目,只要同一数字的牌出现4张正面朝上的牌(比如4个A),则称“开了一对”,当然4个K是不算的。
6.统计一共开了多少对,开了0对称作”极凶”,1~2对为“大凶”,3对为“凶”,4~5对为“小凶”,6对为“中庸”,7~8对“小吉”,9对为“吉”,10~11为“大吉”,12为“满堂开花,极吉”。
输入格式
一共输入13行数据,每行四个数字或字母,表示每堆牌的具体牌型(不区分花色只区分数字),每堆输入的顺序为从上到下。
为了便于读入,用0代表10。同行数字用空格隔开。
输出格式
输出一个整数,代表统计得到的开出的总对数。
输入样例:
8 5 A A
K 5 3 2
9 6 0 6
3 4 3 4
3 4 4 5
5 6 7 6
8 7 7 7
9 9 8 8
9 0 0 0
K J J J
Q A Q K
J Q 2 2
A K Q 2
输出样例:
9
分析:
简单的模拟题。首先考虑几种边界情况,第一种是第13堆牌全是K,四步操作就结束了,相当于开了0对。第二种是比如第一次从第13堆牌上面取到2,放到第二堆上面,然后从第二堆底下抽到的也一直是2,会不会导致第二堆牌抽完导致跳不到其它牌呢?实际上是不会的,因为一个数字的牌最多有4张,第一次从第13堆抽到了2,那么初始的第二堆里必然有一个其它数字牌。
上面的情况实际上在代码中无须考虑,唯一需要注意的是有一个坑,题目将第13堆的四张牌称为生命牌,是否该堆的四张牌被抽完后游戏就结束了呢?如果这样想得到的必然是WA。一般情况下,如果生命牌里没有K,那么这堆牌被抽完K仅仅被扔掉三张。意味着生命牌没了,其实你还有一条命,直到抽到最后一张K才会结束。至于时机,可能是立刻,也可能是抽到的最后一张牌才是K。也就是说,真正的生命牌,是四张K。
下面简单的阐述下思路:生命牌每次从最上面拿,其他牌每次从最底下拿,每次放到一堆牌的最上面。很容易想到用双端队列来存储这些牌,但是其实没必要,可以用基本的数组模拟,采用12个栈和一个队列模拟更为方便。生命堆牌每次从最上面抽取,而最上面的牌是最先读入的,先进先出,符合队列思想。其它堆的牌则是先进后出的,适合用栈模拟。至于从底下或者上面取牌,不过是出栈和出队的操作。将取到的牌放在相应堆的最上面的操作,更没有必要了,只需维护一个数组,记录下该堆牌上面已经被翻开的牌的数目即可。
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
queue<int> q;
stack<int> s[13];
int a[14];
int transfer(char c){
if(c - '0' > 1 && c - '0' < 10) return c - '0';
else if(c == '0') return 10;
else if(c == 'J') return 11;
else if(c == 'Q') return 12;
else if(c == 'K') return 13;
else if(c == 'A') return 1;
}
void solve(){
int u,ans = 0,t = 13;
while(a[13] < 4){//四张K用完
while(t == 13 && q.size()){
t = q.front();
q.pop();
a[t]++;//牌被翻开
}
if(a[13] == 4) break;
u = s[t].top();
s[t].pop();
t = u;
a[t]++;
}
for(int i = 1;i < 13;i++){
if(a[i] == 4) ans++;
}
cout<<ans<<endl;
}
int main(){
char c;
for(int i = 1;i < 13;i++){
for(int j = 0;j < 4;j++){
cin>>c;
s[i].push(transfer(c));
}
}
for(int i = 0;i < 4;i++){
cin>>c;
q.push(transfer(c));
}
solve();
return 0;
}