uva 127 poj 1214 "Accordian" Patience (栈STL运用)

本文详细介绍了如何使用栈和容器优化扑克牌游戏的算法实现,通过改变输入输出方式和使用string类,最终实现了从超时(TLE)到正确解答(AC)的转变。文章还提供了三种不同的实现方式,包括使用栈、使用vector容器加栈以及使用结构体和函数进行匹配判断,以解决游戏中牌的匹配与移动问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意直接荡上来吧:

一副撲克牌有52張牌,首先把紙牌一張一張由左到右排好(不能有重疊,所以共有52堆牌,每堆一張),當某一張牌與他左邊那張牌或者左邊的第三張牌有「Match」的時候,就把這張牌移到那張牌上面去。在這裡兩張牌「Match」指的是這兩張牌的花色(suit)或者點數(rank)一樣。當你做了一個移動之後,要察看是否還可以做其他的移動。在任何時間,只有最上面那張牌可以被移動。如果因為移動一張牌使得產生一個空格(也就是被移動的那堆牌只有一張牌),你必須把右邊所有的牌堆往左移一格。如此不斷的尋找可移動的牌,直到沒有一張牌可以移動遊戲就結束了。

在選擇可以移動的牌的時候可能有些狀況會發生。如果有兩張牌都可以移動,你應該要移動最左邊的那張牌。當一張牌可以被移動到左邊一格,或左邊三格的時候,你必須移動到左邊三格。


TLE了一个晚上,改了输入输出和string类,ac了。


TLE代码:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <stack>
using namespace std;

bool is_match(string s1, string s2)
{
    return (s1[0] == s2[0] || s1[1] == s2[1]);
}

int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif // LOCAL

    string str[53];
    bool flag = true;
    while (cin >> str[0])
    {
        if (str[0] == "#")
            break;
        stack<string> S[53];
        S[0].push(str[0]);
        for (int i = 1; i < 52; i++)
        {
            cin >> str[i];
            S[i].push(str[i]);
        }
        int num = 52;
        while (flag)
        {
            flag = false;
            for (int i = 1; i < num; i++)
            {
                if (!S[i].empty() && i >= 3 && is_match(S[i].top(), S[i - 3].top()))
                {
                    S[i - 3].push(S[i].top());
                    S[i].pop();
                    flag = true;
                    if (S[i].empty())
                    {
                        for (int j = i; j < num - 1; j++)
                            S[j] = S[j + 1];
                        num--;
                    }
                    break;
                }
                if (!S[i].empty() && is_match(S[i].top(), S[i - 1].top()))
                {
                    S[i - 1].push(S[i].top());
                    S[i].pop();
                    flag = true;
                    if (S[i].empty())
                    {
                        for (int j = i; j < num - 1; j++)
                            S[j] = S[j + 1];
                        num--;
                    }
                    break;
                }
            }
        }
        cout << num << " pile";
        if (num > 1)
            cout << "s";
        cout << " remaining:";
        for (int i = 0; i < num; i++)
            cout<<" "<< S[i].size();
        cout << endl;
        flag = true;
    }
    return 0;
}

AC栈做法:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <stack>
using namespace std;

struct Card
{
    char a, b;
} card[53];

bool is_match(Card s1, Card s2)
{
    return (s1.a == s2.a || s1.b == s2.b);
}

int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif // LOCAL


    while (scanf("%c", &card[0].a))
    {
        if (card[0].a == '#')
            break;
        scanf("%c", &card[0].b);
        getchar();
        stack<Card> cards[53];
        cards[0].push(card[0]);
        for (int i = 1; i < 52; i++)
        {
            scanf("%c%c", &card[i].a, &card[i].b);
            cards[i].push(card[i]);
            getchar();
        }
        /*for (int i = 0; i < 52; i++)
        {
            printf("%c%c ", cards[i].top().a, cards[i].top().b);
            if (i == 25)
                printf("\n");
        }
        printf("\n");*/

        bool flag = true;
        int num = 52;
        while (flag)
        {
            flag = false;
            for (int i = 1; i < num; i++)
            {
                if (!cards[i].empty() && i >= 3 && is_match(cards[i].top(), cards[i - 3].top()))
                {
                    cards[i - 3].push(cards[i].top());
                    cards[i].pop();
                    flag = true;
                    if (cards[i].empty())
                    {
                        for (int j = i; j < num - 1; j++)
                            cards[j] = cards[j + 1];
                        num--;
                    }
                    break;
                }
                if (!cards[i].empty() && is_match(cards[i].top(), cards[i - 1].top()))
                {
                    cards[i - 1].push(cards[i].top());
                    cards[i].pop();
                    flag = true;
                    if (cards[i].empty())
                    {
                        for (int j = i; j < num - 1; j++)
                            cards[j] = cards[j + 1];
                        num--;
                    }
                    break;
                }
            }
        }
        /*printf("%d pile", num);
        if (num > 1)
            printf("s");
        printf(" remaining:");*/
        printf("%d piles remaining:", num);
        for (int i = 0; i < num; i++)
            printf(" %d", cards[i].size());
        printf("\n");
    }
    return 0;
}

AC vector容器+栈做法:

#include <iostream>
#include <stack>
#include <vector>
#include <cstdio>
using namespace std;

struct card
{
    char x, y;
    card(char a, char b):x(a),y(b){}
};

bool judge(card a, card b)
{
    return (a.x == b.x || a.y == b.y);
}

int main()
{
    #ifdef LOCAL
    freopen("in.txt", "r", stdin);
    #endif // LOCAL
    char s[3];
    bool flag = true;
    vector< stack<card> > cards;
    while (scanf("%s", s) && s[0] != '#')
    {
        card c(s[0], s[1]);
        stack<card> tmp;
        tmp.push(c);
        cards.push_back(tmp);
        if (cards.size() == 52)
        {
            while (flag)
            {
                int i;
                flag = false;
                for (i = 0; i < cards.size(); i++)
                {
                    if (i > 2 && judge(cards[i].top(), cards[i - 3].top()))
                    {
                        cards[i - 3].push(cards[i].top());
                        cards[i].pop();
                        flag = true;
                        if (cards[i].empty())
                            cards.erase(cards.begin() + i);
                        break;
                    }
                    if (i > 0 && judge(cards[i].top(), cards[i - 1].top()))
                    {
                        cards[i - 1].push(cards[i].top());
                        cards[i].pop();
                        flag = true;
                        if (cards[i].empty())
                            cards.erase(cards.begin() + i);
                        break;
                    }
                }
            }
            if (cards.size() == 1)
                printf("%d pile remaining:", cards.size());
            else
                printf("%d piles remaining:", cards.size());
            for (int i = 0; i != cards.size(); i++)
                printf(" %d", cards[i].size());
            printf("\n");
            flag = true;
            cards.clear();
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值