AcWing 117 占卜DIY

题目描述:

达达学会了使用扑克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;
}

猜你喜欢

转载自blog.csdn.net/qq_30277239/article/details/89045297
117
今日推荐