题目描述: 把52张牌从左到右排好,每张牌自成一个牌堆 (pile)。 当某张牌 与它左边那张牌或者左边第3张牌“match" (花色suit或者点数rank相同)时,就把这张牌移到那张牌上面。移动之后还要查看是否可以进行其他移动。只有位于牌堆顶部的牌才能移动或者参与match.当牌堆之间出现空隙时要立刻把右边的所有牌堆左移格来填补空隙。 如果有多张牌可以移动,先移动最左边的那张牌;如果既可以移一格也可以移3格时, 移3格。按顺序输入52张牌,输出最后的牌堆数以及各牌堆的牌数。
思路:理解好题以后其实并不难,开52个栈进行题目中的描述即可解决
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
struct Card
{
char a,b;
};
int judge(Card x,Card y)
{
return (x.a==y.a||x.b==y.b);
}
int main()
{
Card card;
stack<Card> s[55];
int n=0,i;
while(scanf("%c%c",&card.a,&card.b)&&card.a!='#')
{
getchar();
s[n++].push(card);
if(n==52)
{
int m=1,flag;
while(1)
{
for(i=m; i<n; i++)
{
if(i>=3&&judge(s[i-3].top(),s[i].top()))
{
flag=1;
break;
}
if(i>=1&&judge(s[i-1].top(),s[i].top()))
{
flag=2;
break;
}
}
if(i==n)
break;
if(flag==1)
{
s[i-3].push(s[i].top());
m=i-3;
}
else
{
s[i-1].push(s[i].top());
m=i-1;
}
s[i].pop();
if(s[i].empty())
{
for(int j=i; j<n-1; j++)
s[j]=s[j+1];
while(!s[n-1].empty())
s[n-1].pop();
n--;
}
}
if(n>1) printf("%d piles remaining:",n);
else printf("%d pile remaining:",n);
for(int i=0; i<n; i++)
{
printf(" %d",s[i].size());
while(!s[i].empty())
s[i].pop();
}
printf("\n");
n=0;
}
}
return 0;
}