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("\n");
}

int main() {
    while( Read() ){
        Move();
        Print();
    }
    return 0;
}

 

posted @ 2015-07-31 15:26  Emerald  阅读(361)  评论(0编辑  收藏  举报