题意: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; }