UVa 127"Accordian" Patience解题报告

来源:互联网 发布:寒冷队长知乎 编辑:程序博客网 时间:2024/05/29 19:20

一道链表模拟题,可以用数组做,也可以用链表来模拟过程。用链表模拟比较麻烦,一不小心就被指针搞晕了。但是我想趁机熟悉一下链表的实现,所以用的是链表来做这道题。

其实链表没有想象中可怕,就是要对指针很小心,不然很容易出现环。

思路:从左到右,对每张牌堆的最上面一张牌,向其左边的第三和第一张牌做比较。优先移动到第三张牌上面。每次移动都要重新从第一张牌开始比较,直到所有牌都无法匹配。

#include <iostream>#include <cstring>using namespace std;struct nobe//双向链表存储数据{char value, suit;nobe *next;nobe *pre;};struct record//记录长度与链表的最后节点的指针{int len;nobe *last;};record piles[52];void creat_list(char, char, int);int game();void cover(record &, record &);void move(int, int);void show(int n);int main(){//freopen("data.txt", "r", stdin);//freopen("output.txt", "w", stdout);while (true){char a, b;scanf("%c", &a);if(a == '#')break;scanf("%c", &b);creat_list(a, b, 0);for(int i = 1; i <= 51; i++){getchar();scanf("%c%c", &a, &b);creat_list(a, b, i);}int count = game();if(count > 1)              printf("%d piles remaining:", count);          else              printf("%d pile remaining:", count);          for(int i = 0; i < count; i++)printf(" %d", piles[i].len); printf("\n");getchar();}}void creat_list(char a, char b, int n){nobe *s;s = new nobe;s->value = a;s->suit = b;s->next = NULL;s->pre = NULL;piles[n].last = s;piles[n].len = 1;}int game(){int count = 52;while (true){int flag = 0;for(int i = 1; i < count; i++){if(i - 3 >= 0 &&(piles[i].last->value == piles[i - 3].last->value ||piles[i].last->suit == piles[i - 3].last->suit))//先比较左边第三个{flag = 1;cover(piles[i], piles[i - 3]);}if(flag == 0 && i - 1 >= 0 && (piles[i].last->value == piles[i - 1].last->value ||piles[i].last->suit == piles[i - 1].last->suit))//再比较左边第一个{flag = 1;cover(piles[i], piles[i - 1]);}if(flag && piles[i].last == NULL)//有一个牌堆空,将空格填满{count--;move(count, i);}if(flag)//如果有移动break;}/*show(count);printf("\n");*/if(flag == 0)//如果全部循环完,牌没有变动break;}return count;}void cover(record &x, record &y){x.len--;//更改长度y.len++;nobe * s = x.last;nobe * p = new nobe;p->value = x.last->value;p->suit = x.last->suit;y.last->next = p;//建立新的后驱指针p->pre = y.last;//建立新的前驱指针p->next = NULL;//删除交换节点的后驱y.last = p;//更新最后节点指针if(x.len != 0)//如果最后节点的前驱为空,说明只剩下一个{x.last->pre->next = NULL;//把最后节点的前驱节点的next置零x.last = x.last->pre;//更新最后的节点指针}elsex.last = NULL;delete s;}void move(int count, int n){for(int i = n; i < count; i++)piles[i] = piles[i + 1];}void show(int n){for(int i = 0; i < n; i++){nobe *p = piles[i].last;while (p != NULL){printf("%c%c ", p->value, p->suit);p = p->pre;}printf("\n");}}



0 0
原创粉丝点击