"Accordian" Patience (UVa 127) 双向链表 栈
Posted 淡蓝色光
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了"Accordian" Patience (UVa 127) 双向链表 栈相关的知识,希望对你有一定的参考价值。
题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=63
思路:
从第一个牌堆开始,向右进行遍历。若存在左边第三个牌堆,则优先考虑能否移动到左边第三个牌堆,若不存在或不能移动,再考虑左边第一个牌堆,若都不能移动,则继续考虑下一个牌堆。由于“如果有多张牌可以移动,先移动最左边的牌”,因此进行移动操作以后,要从移动到的那张牌堆开始考虑。每次移动操作都进行牌堆是否为空判断。
PS: 不知道为什么,用 cout 输出的话,一提交就 WA,改成 printf 就AC了,活生生卡了2天。
代码:
#include <iostream> #include <stack> #include <cstdlib> using namespace std; const int MAX = 53; struct Node{ stack<string> stk; }; int r[MAX], l[MAX]; //结点的右边、左边 Node node[MAX]; //牌堆 void link(int a, int b); //连接两个结点 void deleteNode(int a); //删除结点 void init(); //初始化链表 bool canMove(int a, int b); //判断能否将 b 的牌顶移到 a void move(int a, int b); //将 b 顶部的牌移到 a 牌堆 void check(int a); //如果 a 的牌堆为空,删除 int treblePre(int a); //a 前面第三个结点,若不存在,返回 0 bool input(); //输入,若结束返回 false void output(); //输出 int main(){ //freopen("input.txt", "r", stdin); while(input()){ int i=r[0]; while(i != 0){ //一直做到没有后继 int pre1 = treblePre(i); //前面第三个牌堆 int pre2 = l[i]; //前面第一个牌堆 if(pre1 != 0){ //如果前面第三个牌堆存在 if(canMove(pre1, i)){ move(pre1, i); //就进行移动 check(i); //若为空,删除 i = pre1; //从 pre1 牌堆开始考虑 continue; } } if(pre2 != 0){ if(canMove(pre2, i)){ move(pre2, i); //就进行移动 check(i); //若为空,删除 i = pre2; //从 pre2 牌堆开始考虑 continue; } } i = r[i]; //如果不能移动,则考虑下一堆 } output(); //输出 } return 0; } void link(int a, int b){ r[a] = b; l[b] = a; } void deleteNode(int a){ link(l[a], r[a]); } void init(){ for(int i=0; i<MAX-1; i++){ //初始化链 link(i, i+1); } r[52] = 0; } bool canMove(int a, int b){ string s1 = node[a].stk.top(); string s2 = node[b].stk.top(); if(s1[0] == s2[0] || s1[1] == s2[1]){ return true; } return false; } void move(int a, int b){ node[a].stk.push(node[b].stk.top()); node[b].stk.pop(); } void check(int a){ if(node[a].stk.empty()){ deleteNode(a); } } bool input(){ string s[MAX]; init(); cin >> s[1]; if(s[1] == "#") //结束返回 false return false; for(int i=2; i<MAX; i++){ cin >> s[i]; } for(int i=1; i<MAX; i++){ node[i].stk.push(s[i]); } } int treblePre(int a){ int b = a; for(int i=1; i<=3; i++){ b = l[b]; if(b == 0) //若不存在 返回 0 return 0; } return b; } void output(){ int sum; int cnt = 0; for(int i=r[0]; i!=0; i=r[i]){ cnt++; } if(cnt == 1) printf("1 pile remaining:"); else printf("%d piles remaining:", cnt); for(int i=r[0]; i!=0; i=r[i]){ sum = 0; while(!node[i].stk.empty()){ node[i].stk.pop(); sum++; } printf(" %d", sum); } printf("\n"); }
以上是关于"Accordian" Patience (UVa 127) 双向链表 栈的主要内容,如果未能解决你的问题,请参考以下文章
习题 6-9 UVA - 127"Accordian" Patience
"Accordian" Patience (UVa 127) 双向链表 栈