//POJ1214,转自UVA127,只是UVA上面要注意当pile为1时,不是复数piles形式! //其实是简单的链表,思路很清晰,想象成现实的挪纸牌,注意只能挪最上面的一张。挪走之后原来的链怎么办?它原本下面是否有card? //原本的后面是否有card?挪去容易挪走"难",这个挪走关键要思路清晰,链的断开和链接都要"有链可寻".折腾了好久,早上起来理清思路,直接AC之. #include <stdio.h> #include <stdlib.h> typedef struct Card { char rank; char suit; struct Card *next, *pre, *up, *down; }Node; int main() { int Match (Node* A, Node* B); void Move (Node *p, Node *pp, int i); int i, count; int p1flag, p3flag;//左1左3存在的标志 int a[1000];//把每堆的牌数存到数组 char c; Node *head, *p, *q, *p1, *p3, *t, *d; freopen("in.txt", "r", stdin); while ((c = getchar())!='#') { i=0; head = (Node *)malloc(sizeof(Node)); head->next = NULL; head->pre = NULL; head->up = NULL; head->down = NULL; head->rank = '0'; head->suit = '0'; p = (Node *)malloc(sizeof(Node)); p->next = NULL; p->pre = NULL; p->up = NULL; p->down = NULL; p->rank = c; p->suit = getchar(); getchar();//读空格 head->next = p; p->pre = head; i++; for (;i<52; i++) { q = (Node *)malloc(sizeof(Node)); q->next = NULL; q->pre = NULL; q->up = NULL; q->down = NULL; q->rank = getchar(); q->suit = getchar(); getchar();//读空格 p->next = q;//q指向p q->pre = p;// p指向q p = q; } for (p=head->next; p!=NULL; p=p->next) { p1flag = 0; p3flag = 0; if (p->pre)//如果左1结点存在 { if (p->pre->rank!='0')//如果左1不是head结点 { p1 = p->pre; p1flag = 1; } else { continue; } if (p->pre->pre)//如果左2存在 { if (p->pre->pre->pre)//如果左3存在 { if (p->pre->pre->pre->rank!='0')//左三不为head { p3 = p->pre->pre->pre; p3flag = 1; } } } if (p3flag==0 && p1flag==1 && Match(p, p1))//左1存在且匹配,左三不存在 { t = p1->pre; Move(p, p1, 1); p = t; continue; } if (p1flag==1 && p3flag==1)//如果左1和左3都存在 { if (!Match(p, p1)&&Match(p, p3) || Match(p, p1)&&Match(p, p3))//与左1左3都匹配或只与左3匹配 { t = p3->pre; Move(p, p3, 3); p = t; continue; } if (Match(p, p1) && !Match(p, p3))//只与左1匹配 { t = p1->pre; Move(p, p1, 1); p = t; } } } }//for p = head->next; i=0; for (; p!=NULL; p = p->next) { d = p; count=0; while (d) { count++; d = d->down; } a[i++] = count; } printf("%d piles remaining:", i); for (count=0; count<i; count++) { printf(" %d",a[count]); } printf("/n"); } return 0; } int Match (Node* A, Node* B) { if (A->rank==B->rank || A->suit==B->suit) { return 1; } return 0; } void Move(Node *p, Node *pp, int i) { if (i == 1) { if (p->down != NULL) { p->down->next = p->next; if (p->next != NULL) { p->next->pre = p->down; } p->next = p->down; p->next->pre = p; } p->pre = pp->pre; pp->pre->next = p; pp->up = p; p->down = pp; } else { if (p->down) { if (p->next != NULL) { p->next->pre = p->down; } p->pre->next = p->down; p->down->pre = p->pre; p->down->next = p->next; } else { if (p->next != NULL) { p->next->pre = p->pre; } p->pre->next = p->next; } p->next = pp->next; p->next->pre = p; p->pre = pp->pre; p->pre->next = p; pp->up = p; p->down = pp; } }