题意:有52张牌从左往右放在桌子上,一开始每张牌算一个牌堆。如果两张牌可以匹配当且仅当这两张牌的花色或者点数相同。现在每个牌堆的最上面的牌可以和它左边的第一个牌堆上的第一张牌或左边第三个牌堆上的第一张牌匹配,如果匹配成功,就把这张牌放到对应的牌堆上。如果都能匹配,优先去和左边第三个牌堆匹配。存在多个牌堆可以发生匹配的情况,优先去执行靠左的牌堆。如果一个牌堆为空,这个牌堆就不再用了,右边所有牌都向左移动一个位置。一直执行到无法匹配时,剩余每个牌堆牌的数量。
思路:用链表模拟一下过程。next[i]表示编号为i的牌堆右边牌堆的编号。last[i]表示编号为i的牌堆左边牌堆的编号。如果牌堆i的牌数变为0,那么就把i删除掉,last[i]的next应该指向next[i],next[i]的last应该指向last[i](先判断i是不是最后一个牌堆)。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)
#define Clean(x,y) memset(x,y,sizeof(x))
int next[60],last[60];
struct node
{
char x,y;
node(char tx = ' ',char ty = ' ')
{
x = tx;
y = ty;
}
};
vector<node> p[60];
bool init()
{
char tx,ty;
tx = getchar();
if ( tx=='#' ) return false;
rep(i,1,52)
{
p[i].clear();
if( i!=1 ) tx = getchar();
ty = getchar();
getchar();
p[i].push_back( node(tx,ty) );
}
last[1] = 0;
next[52] = -1;
rep(i,1,51) next[i] = i + 1;
rep(i,2,52) last[i] = i - 1;
return true;
}
bool match(node a,node b)
{
if ( a.x == b.x || a.y == b.y ) return true;
return false;
}
void move(int x,int y) //x牌堆上的牌放到y牌堆上
{
p[y].push_back( p[x][p[x].size()-1] );
p[x].pop_back();
if ( p[x].size() == 0 ) //删除x牌堆
{
int L = last[x];
int R = next[x];
next[ L ] = R;
if ( R!=-1 ) last[R] = L;
}
}
bool check(int x)
{
if ( p[x].size() == 0 ) return false;
int x1,x2;
x1 = x;
rep(i,1,3) x1 = last[x1];//左边第三个牌堆
x2 = last[x]; //左边第一个牌堆
if ( x1 != 0 && match( p[x1][ p[x1].size()-1 ] , p[x][p[x].size()-1] ) )
{
move(x,x1);
}
else if ( x2 != 0 && match( p[x2][ p[x2].size()-1 ] , p[x][p[x].size()-1] ) )
{
move(x,x2);
}
else return false;
return true;
}
int main()
{
while(init())
{
bool can = true;
while(can)
{
can = false;
rep(i,2,52) //第一个牌堆前面没有牌堆与其去匹配
if ( check(i) ) {can = true; break;}
}
int k = 1;
int num = 0;
while( k!=-1 )
{
num++;
k = next[k];
}
if ( num == 1 ) printf("%d pile remaining:",1);
else printf("%d piles remaining:",num);
k = 1;
rep(i,1,num)
{
printf(" %d",p[k].size());
k = next[k];
}
puts("");
}
return 0;
}