• Uva 127 "Accordian" Patience


    题意:52张牌,初始每张牌各成一堆,且从左到右成一排摆放。每堆的最上面一张可以移动到左边第一堆最上面或左边第三堆,如果匹配的话。匹配的条件:花色相同或牌面值相同。而且只有牌堆中最上面的牌可以参与匹配,如果一个牌堆空了,则空牌堆右边的牌堆向左移动一个牌堆。如果一张牌同时可以移动三格或一个,则优先移动三格。如果有多张可以移动,则优先移动最左边的。

    最后题目要求输出剩余牌堆数,以及每个牌堆中牌的数量。

    思路:可以将每个牌堆看作一个双向列表,当一个牌堆空了时,就将空牌堆的左右两结点相连接。以此从左到右进行比较,并在匹配时模拟移动。当需要的注意的时,发生移动之后,进行比较的起点发生了变化。

      举例:AD 7S AH 7D 5C -----

      此是当比较7D时,此时7D可以移动到AD上,形成7D(AD),7S, AH, 5C----此时,如果7D左边还有匹配,则先让7D移动,此数7D以不用移动;下一个比较起点应该是7S,而不是5C,否则7S将不能移动到7D上。

    /*
        UvaOJ 127
        Emerald
        Fri 31 Jul 2015
     */
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    
    using namespace std;
    
    struct Pile{
        std::vector<string> v;
        int left, right;
    };
    
    const int MAXN = 52 + 5;
    Pile pile[MAXN];
    
    bool Read() {
        string card;
        pile[0].right = 1;
        pile[53].left = 52;
        for(int i=1; i<52 + 1; i++) {
            cin >> card;
            if(card=="#") {
                return false;
            }
            pile[i].left = i - 1;
            pile[i].right = i + 1;
            pile[i].v.clear();
            pile[i].v.push_back(card);
        }
        return true;
    }
    
    int Back(int start, int step) {
        while(start > 0 && step) {
            start = pile[start].left;
            step --;
        }
        return start > 0 ? start : -1;
    }
    
    bool Match(string &a, string &b) {
        return (a[0] == b[0]) || (a[1] == b[1]);
    }
    
    void Put(int former, int pos) {
        pile[former].v.push_back( pile[pos].v.back() );
        pile[pos].v.erase( pile[pos].v.end()-1 );
        if(pile[pos].v.size() == 0) {
            pile[ pile[pos].left ].right = pile[pos].right;
            pile[ pile[pos].right ].left = pile[pos].left;
        }
    }
    
    void Move() {
        int pos = 1;
        while(pos!=53) {
            int former = Back(pos, 3);
            if(former != -1 && Match( pile[former].v.back(), pile[pos].v.back() ) ) {
                Put( former, pos );
                pos = former;
                continue;   
            }
            former = Back(pos, 1);
            if(former != -1 && Match( pile[former].v.back(), pile[pos].v.back() ) ) {
                Put( former, pos );
                pos = former;
                continue;
            }
            pos = pile[pos].right;
        }
    }
    
    void Print() {
        int pos = 0;
        std::vector<int> result;
        while(pile[pos].right!=53) {
            pos = pile[pos].right;
            result.push_back( pile[pos].v.size() );
        }
        printf("%d pile%s remaining:", (int)result.size(), result.size() > 1 ? "s":"");
        for(int i=0; i<(int)result.size(); i ++) {
            printf(" %d", result[i]);
        }
        printf("
    ");
    }
    
    int main() {
        while( Read() ){
            Move();
            Print();
        }
        return 0;
    }
    
  • 相关阅读:
    mysql数据库启动停止
    事务的隔离级别
    排序之选择排序
    排序之希尔排序
    排序之折半插入排序
    排序之直接插入排序
    排序之冒泡排序
    排序之快速排序
    字符串拷贝和拼接
    字符串旋转问题
  • 原文地址:https://www.cnblogs.com/Emerald/p/4692284.html
Copyright © 2020-2023  润新知