https://vjudge.net/problem/UVA-127
题目
把52张纸牌从左到右排好,每张牌自成一个牌堆(pile)。当某张牌与它左边那张牌或者左边第三张牌“match”(花色suit或者点数mark相同)时,就把这张牌移到那张牌上面。移动之后还要查看是否可以进行其他移动。只有位于牌堆顶部的牌才能移动或参与match。当牌堆之间出现间隙时要立刻把右边的所有牌堆左移一格来填补空隙。如果有多张牌可以移动,先移动最左边的那张牌;如果既可以移一格,又可以移3格,那么移动三格。按顺序输入52张牌,输出最后的牌堆数以及各堆牌的排数。
题解
用双向链表= =
难在模拟……
开始想过优化
从左到右检查能不能移动,如果能移动就移动。移动一次以后在移动到的位置开始检查,因为这个位置左边已经检查过了,右边可能可以移动,但这个位置也可能可以移动,并且这个位置在右边的左边,如果可以移动应该是优先移动。
花了4小时
AC代码
#include<bits/stdc++.h>
using namespace std;
#define REP(i,x,y) for(register int i=(x); i<(y); i++)
#define REPE(i,x,y) for(register int i=(x); i<=(y); i++)
#ifdef sahdsg
#define DBG(a,...) printf(a, ##__VA_ARGS__)
#else
#define DBG(a,...) (void)0
#endif
#define MAXN 107
char t[7];
char node[MAXN][2][MAXN];
int nodei[MAXN];
int nxt[MAXN], prv[MAXN];
inline int getl3(int x) {
REP(i,0,3) {
x=prv[x];
if(x==-1) return -1;
}
return x;
}
inline int getr3(int x) {
REP(i,0,3) {
x=nxt[x];
if(x==-1) return -1;
}
return x;
}
inline int getl1(int x) {
return prv[x];
}
inline bool match(int x,int y) {
return node[x][0][nodei[x]-1]==node[y][0][nodei[y]-1] || node[x][1][nodei[x]-1]==node[y][1][nodei[y]-1];
}
inline void link(int l, int r) {
if(~l)nxt[l]=r;
if(~r)prv[r]=l;
}
int main() {
#ifdef sahdsg
freopen("in.txt", "r", stdin);
#endif
while(scanf("%s", t) && t[0]!='#') {
node[1][0][0]=t[0],node[1][1][0]=t[1];
nxt[0]=1,prv[1]=0,prv[0]=-1;
nodei[1]=1;nxt[1]=2;
REPE(i,2,52) {
scanf("%s", t);
node[i][0][0]=t[0],node[i][1][0]=t[1];
nxt[i]=i+1;prv[i]=i-1;
nodei[i]=1;
}
nxt[52]=-1;
// DBG("#1\n");
for(int i=nxt[0];~i;i=nxt[i]) {
int l3=getl3(i);
int p=i;
if(~l3 && match(l3,i)) {
p=l3;l3=getl3(p);
} else {
int l1=getl1(p);
if(~l1 && match(l1,i)) {
p=l1;l1=getl1(p);
}
}
if(p!=i) {
node[p][0][nodei[p]]=node[i][0][nodei[i]-1];
node[p][1][nodei[p]]=node[i][1][nodei[i]-1];
nodei[p]++;
nodei[i]--;
if(nodei[i]==0)
link(prv[i],nxt[i]);
i=prv[p];
}
}
int ccnt=0;
REPE(i,1,52) {
if(nodei[i]) {
ccnt++;
}
}
if(ccnt==1)
printf("%d pile remaining:", ccnt);
else
printf("%d piles remaining:", ccnt);
REPE(i,1,52) {
if(nodei[i]) {
printf(" %d", nodei[i]);
// DBG("-%c%c\n", node[i][0][nodei[i]-1], node[i][1][nodei[i]-1]);
}
}
putchar('\n');
}
return 0;
}