思路:本题主要考察数据结构和stl的使用。牌堆用stack存储,再用list把stack链接起来。由于要求一张牌移动后应当查看该涨牌是否可以继续移动,故使迭代器指向其移动后的位置,以便判断其是否可以继续移动。
输出:本题应当注意pile输出的单复数。
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<cstdio>
#include<iostream>
#include<string>
#include<numeric>
#include<algorithm>
#include<map>
#include<vector>
#include<set>
#include<sstream>
#include<fstream>
#include<queue>
#include<stack>
#include<unordered_map>
#include<tuple>
#include<deque>
#include<functional>
#include<iterator>
#include<array>
#include<list>
#include<forward_list>
using namespace std;
struct Card
{
char suit;
char rank;
Card(char _suit, char _rank)
:suit(_suit), rank(_rank) {
}
Card(const Card& c)
{
suit = c.suit;
rank = c.rank;
}
bool match(const Card& c2)
{
return suit == c2.suit || rank == c2.rank;
}
};
typedef stack<Card> stcard;
list<stcard>piles;
list<stcard>::iterator minus3(list<stcard>::iterator iter)
{
for (int i = 0; i < 3; ++i)
{
if (iter == piles.begin())
return piles.end();
--iter;
}
return iter;
}
bool ifMatchThenDelete(list<stcard>::iterator iterleft, list<stcard>::iterator& stitercur)
{
Card cur = stitercur->top();
Card leftcard = iterleft->top();
if (cur.match(leftcard))
{
iterleft->push(cur);
stitercur->pop();
if (stitercur->empty())
{
piles.erase(stitercur);
}
stitercur = iterleft;
return true;
}
return false;
}
int main() {
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
char card[4];
while (scanf("%s", card) == 1 && card[0] != '#')
{
for (auto& elem : piles)
{
while (!elem.empty())
elem.pop();
}
piles.clear();
stcard mystack;
mystack.push(Card(card[1], card[0]));
piles.push_back(std::move(mystack));
for (int i = 1; i < 52; ++i)
{
scanf("%s", card);
stcard mystack;
mystack.push(Card(card[1], card[0]));
piles.push_back(std::move(mystack));
}
list<stcard>::iterator stitercur = ++piles.begin();
while (stitercur != piles.end())
{
if (stitercur == piles.begin())
{
++stitercur;
continue;
}
list<stcard>::iterator stiterleft1 = --stitercur;
++stitercur;
list<stcard>::iterator stiterleft3 = minus3(stitercur);
if (stiterleft3 != piles.end())
{
if (ifMatchThenDelete(stiterleft3, stitercur))
continue;
}
if (ifMatchThenDelete(stiterleft1, stitercur))
continue;
++stitercur;
}
printf("%d pile%s remaining:", (int)piles.size(), piles.size() > 1 ? "s" : "");
for (auto& elem : piles)
{
printf(" %d", (int)elem.size());
}
puts("");
}
}