其實可以使用在單一空間上表示多個stack的方式,
不過這樣要移來移去,好累啊……
都給每個pile一個stack不就很方便嗎!
pile用linked list實作,
(本來想用array,但是每次empty就要copy,超麻煩)
每個pile各有一個stack。
從第一個pile到最後一個pile。
每次都先-3,再-1。
每次減完要判斷是否在pile中,
若在pile中要檢查是否match,
若match,就做pop跟push。
pop完要判斷該pile是否empty,
若empty就移出linked list。
之後移到push的pile上繼續做-3、-1的動作。
若-3與-1皆沒match,那就移到下一個pile繼續-3、-1。
一次就AC,超爽的~
/* ACM 127 "Accordian" Patience * mythnc * 2012/01/12 17:02:02 * run time: 0.296 */ #include <stdio.h> #include <string.h> #define MAX 52 #define MAXCHAR 3 typedef struct pile { char card[MAX][MAXCHAR]; int count; struct pile *next, *pre; } Pile; typedef enum {FALSE = 0, TRUE} bool; void input(Pile *); int simulate(Pile *); bool match(Pile *, Pile *); void push(Pile *, char *); void pop(Pile *, char *); bool empty(Pile *); void relink(Pile *); void output(Pile *, int); int main(void) { Pile p[MAX]; int n; while (scanf("%s", p[0].card[0]) && p[0].card[0][0] != '#') { input(p); n = simulate(p); output(p, n); } return 0; } /* input: receive input data and initialize */ void input(Pile *p) { int i; p[0].count = 1; p[0].pre = NULL; p[0].next = &p[1]; for (i = 1; i < MAX; i++) { scanf("%s", p[i].card[0]); p[i].count = 1; p[i].pre = &p[i - 1]; if (i != MAX - 1) p[i].next = &p[i + 1]; else p[i].next = NULL; } } /* simulate: simulate Accordian */ int simulate(Pile *head) { int n, i; Pile *pt, *cmp; char s[MAXCHAR]; n = MAX; for (pt = head; pt;) { /* 3rd pile to the left */ for (i = 1, cmp = pt->pre; cmp && i < 3; cmp = cmp->pre, i++) ; if (cmp && match(pt, cmp)) { pop(pt, s); push(cmp, s); if (empty(pt)) { relink(pt); n--; } pt = cmp; continue; } /* neighbour on the left */ cmp = pt->pre; if (cmp && match(pt, cmp)) { pop(pt, s); push(cmp, s); if (empty(pt)) { relink(pt); n--; } pt = cmp; continue; } pt = pt->next; } return n; } /* match: match condition */ bool match(Pile *p, Pile *q) { return q->card[q->count - 1][0] == p->card[p->count - 1][0] || q->card[q->count - 1][1] == p->card[p->count - 1][1]; } /* push: put s in top of p */ void push(Pile *p, char *s) { strcpy(p->card[p->count++], s); } /* pop: pop out the top card */ void pop(Pile *p, char *s) { strcpy(s, p->card[--p->count]); } /* empty: return TRUE if stack is empty * else return FALSE */ bool empty(Pile *p) { return p->count == 0; } /* relink: rearrange linked list */ void relink(Pile *p) { if (p->pre) p->pre->next = p->next; if (p->next) p->next->pre = p->pre; } /* output: output result */ void output(Pile *p, int n) { if (n == 1) { printf("1 pile remaining: 52\n"); return; } printf("%d piles remaining:", n); for (; p; p = p->next) printf(" %d", p->count); putchar('\n'); }
沒有留言:
張貼留言