uva 127 ``Accordian'' Patience
//完全自己写的代码,用链表写的,很多细节没有修改,明天再改,时间是0.544
//关键是find_3和find_1和swap函数的使用,注意细节,注意有的内存是一定要free释放//掉的,注意指针的使用,有的是把指针的值传递过去,有的是把指针变量本身的地址传递//过去,两者完全不同,注意看
#include <stdio.h> #include <string.h> #include <stdlib.h> #define LEN1 sizeof(struct card) #define LEN2 sizeof(struct list) #define MAX 52 struct card { char s[3]; struct card *next; }; struct list { int count; struct list *prior,*next; struct card *head; }*L; void test_print() { struct list *temp=L; while(temp) { printf("count=%d %s\n",temp->count,temp->head->s); temp=temp->next; } temp=L; while(temp->next) temp=temp->next; while(temp) {printf("count=%d %s\n",temp->count,temp->head->s); temp=temp->prior;} } void print_card() { struct list *p; struct card *temp; p=L; while(p) { printf("count=%d ",p->count); temp=p->head; while(temp) {printf("%s ",temp->s); temp=temp->next;} printf("\n"); p=p->next; } printf("****************************\n"); } void swap(struct list *s1 , struct list* *s2) //是将s2移动到s1上面 { struct list *p1,*p2,*p3,*p; struct card *temp; if((*s2)->count==1) //只有唯一一个牌了 { p=(*s2); p1=(*s2)->prior; p2=(*s2)->next; if(p2) {p1->next=p2; p2->prior=p1;} else p1->next=p2; temp=p->head; s1->count++; temp->next=s1->head; s1->head=temp; free(p); } else { p=(*s2); p->count--; temp=p->head; p->head=temp->next; s1->count++; temp->next=s1->head; s1->head=temp; } } int find_3(struct list* *s) {//将一个牌的位置传递过来,寻找它的左边第3个牌是否匹配,不匹配有两种情况,一是根本没有这个牌,而是有但不匹配 int i; struct list *temp=(*s); for(i=1; i<=3 && temp; i++) temp=temp->prior; if(!temp || (temp->head->s[0]!=(*s)->head->s[0] && temp->head->s[1]!=(*s)->head->s[1]) ) return 0; //前面已经不足3个了 else {swap(temp , s); (*s)=temp; /*print_card();*/ return 1;} } int find_1(struct list* *s) {//将一个牌的位置传递过来,寻找它的左边第1个牌是否匹配,不匹配有两种情况,一是根本没有这个牌,而是有但不匹配 struct list *temp=(*s)->prior; if(!temp || (temp->head->s[0]!=(*s)->head->s[0] && temp->head->s[1]!=(*s)->head->s[1]) ) return 0; else {swap(temp , s); (*s)=temp; /*print_card();*/return 1;} } int main() { struct list *l1,*l2; struct card *H,*h1,*h2; int count,i,f; int a[MAX]; while(1) { L=l1=(struct list*)malloc(LEN2); L->prior=NULL; L->next=NULL; L->count=1; L->head=(struct card*)malloc(LEN1); L->head->next=NULL; scanf("%s",L->head->s); if(!strcmp(L->head->s , "#")) {free(L); return 0;} for(i=2; i<=MAX; i++) { l2=(struct list*)malloc(LEN2); l2->prior=l1; l2->next=NULL; l2->count=1; l2->head=(struct card*)malloc(LEN1); l2->head->next=NULL; l1->next=l2; l1=l2; scanf("%s",l2->head->s); } // test_print(); l1=L; while(l1) { f=find_3(&l1); if(f) continue; f=find_1(&l1); if(f) continue; l1=l1->next; } l1=L; count=0; while(l1) {a[count]=l1->count; count++; l1=l1->next;} if(count==1) printf("1 pile remaining: 52\n"); else { printf("%d piles remaining:",count); for(i=0; i<count; i++) printf(" %d",a[i]); printf("\n"); } } return 0; }