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