题意:
按从左至右的顺序发牌,并摆成一行,发牌不要相互重叠。游戏中一旦出现任何一张牌与它左边的第一张或第三张“匹配”,即花色或点数相同,则须立即将其移动到那张牌上面。如果牌被移动后又出现了上述情况,则需再次向左移动。每叠牌只能移动最上面的一张。如果一叠牌被移空,应该立即将右边各叠整体向左移动,补上这个空隙。依次将整副牌都发完,并不断的向左合并。如果全部移动结束后整副牌都放成了一叠,则游戏胜利。
分析:
用sum表示有多少个牌挪动了,最后输出52-sum。判断是否能放到左边第三张的时候需要注意再前面是否有空位置,空位置不算数。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
char card[54][54][3];
int top[54];
int sum;
int match( char* a, char *b )
{
return (a[0] == b[0] || a[1] == b[1]);
}
int deal(int now,int s)
{
int cont=0,temp=now;
while(temp>=0&&cont<s)
{
if(top[--temp]>=0)
cont++;
}//cout<<cont<<endl;
if(temp>=0&&match(card[now][top[now]],card[temp][top[temp]]))
{
top[temp]++;
card[temp][top[temp]][0]=card[now][top[now]][0];
card[temp][top[temp]][1]=card[now][top[now]][1];
if (--top[now]<0)
sum ++;
return temp;
}
else
return -1;
}
int main()
{
while(scanf("%s",card[0][0])&&card[0][0][0]!='#')
{
int i,j;
for(i=1;i<52;i++)
scanf("%s",card[i][0]);
for(i=0;i<52;i++)
top[i]=0;
sum=0;
for(int now=1;now<52;)
{
while(top[now]<0)
now++;
//cout<<now<<endl;
int save=deal(now,3);
//cout<<save<<endl;
if(save>= 0 )
now=save;
else
{
save=deal(now,1);
//cout<<1<<" "<<save<<endl;
if(save >= 0)
now=save;
else
now++;
}
//cout<<endl;
}
printf("%d pile",52-sum);
if (51>sum)
printf("s");
printf(" remaining:");
for (i=0;i<52;++i)
if (top[i]>=0)
printf(" %d",top[i]+1);
printf(" ");
}
}