UVa 127 - "Accordian" Patience POJ 1214 链表题解

UVa和POJ都有这道题。

不同的是UVa要求区分单复数,而POJ不要求。

使用STL做会比较简单,这里纯粹使用指针做了,非常麻烦的指针操作,一不小心就错。调试起来还是非常费力的

本题理解起来也是挺费力的,要搞清楚如何模拟也不容易啊,读题要很仔细。

纯指针的操作挺快的吧。不过POJ 0ms,而UVa就0.2左右了。

三相链表:

1 只要有叠起来的牌,那么就使用一个down指针指向下面的牌就可以了。

2 使用双向链表,可以方便前后遍历。

3 记得有了更新牌之后,又要重新开始检查是否需要更新牌,这是模拟的需要,不然或WA的。

#include <stdio.h>

struct Node
{
	int size;
	Node *pre, *post;
	Node *down;
	char a, b;
	Node () : pre(NULL), post(NULL), down(NULL), size(1) {}
};

//insert n to m position
inline void insertNode(Node *&m, Node *&n)
{
	n->post = m->post;
	n->pre = m->pre;
	if (m->post) m->post->pre = n;//小心断链
	if (m->pre) m->pre->post = n;//小心断链
}

inline void takeoutNode(Node *&n)
{
	if (n->down)
	{
		Node *down = n->down;
		insertNode(n, down);
		return;
	}
	if (n->pre) n->pre->post = n->post;
	if (n->post) n->post->pre = n->pre;
}

inline void inStackNode(Node *&m, Node *&n)
{
	n->size = m->size+1;
	insertNode(m, n);
	n->down = m;
}

inline bool checkMovable(Node *n, Node *m)
{
	return n->a == m->a || n->b == m->b;
}

inline void pre3(Node *&n)
{
	if (n->pre) n = n->pre;
	if (n->pre) n = n->pre;
	if (n->pre) n = n->pre;
}

inline void pre1(Node *&n)
{
	if (n->pre) n = n->pre;
}

inline void deleteNodes(Node *&n)
{
	while (n)
	{
		Node *p = n->post;
		while (n)
		{
			Node *d = n->down;
			delete n; n = NULL;
			n = d;
		}
		n = p;
	}
}

int main()
{
	Node *head = new Node; //Dummy head
	while (true)
	{
		Node *it = new Node;
		it->a = getchar();
		if (it->a == '#') break;
		it->b = getchar();
		getchar();

		head->post = it;//initialize chain
		it->pre = head;

		for (int i = 1; i < 52; i++)
		{
			Node *p = new Node;
			p->a = getchar();
			p->b = getchar();
			getchar();
			it->post = p;
			p->pre = it;
			it = p;
		}
		bool checkMove = true;
		while (checkMove)
		{
			checkMove = false;
			it = head->post;
			while (it)
			{
				Node *post = it->post;
				Node *p = it;
				pre3(p);
				if (p && p != head && checkMovable(p, it))
				{
					checkMove = true;
					takeoutNode(it);
					inStackNode(p, it);//调用参数不要乱了
					break;
				}
				p = it;
				pre1(p);
				if (p && p != head && checkMovable(p, it))
				{
					checkMove = true;
					takeoutNode(it);
					inStackNode(p, it);
					break;//题意,理解
				}
				it = post;
			}//while (it)
		}//while (checkMove && piles > 1)
		it = head->post;
		int piles = 0;
		while (it)
		{
			piles++;
			it = it->post;
		}
		if (piles == 1) printf("%d pile remaining:", piles);
		else printf("%d piles remaining:", piles);
		it = head->post;
		while (it)
		{
			printf(" %d", it->size);
			it = it->post;
		}
		putchar('\n');
		deleteNodes(head->post);
	}//while (true)
	delete head;
	return 0;
}

UVa 127 - "Accordian" Patience POJ 1214 链表题解

时间: 2024-09-30 19:57:17

UVa 127 - "Accordian" Patience POJ 1214 链表题解的相关文章

uva 127 &quot;Accordian&quot; Patience(手风琴纸牌)

用 栈 stack 来处理. 直接根据题目描述写就可以.不要忘记每组数据最后的清空栈堆. 题目大意: 给定52张的扑克牌,现在要求对扑克牌进行整理,对于每一张扑克牌,如果左边的第三张存在那么就去判断这一张是否和第三张满足花色或卡片值相同,如果满足则把这一张移动到左边的第三张,否则去判断左边的第一张是否和这一张满足条件:如果左边的第三张不存在那么只要去判断左边的第一张即可.最后输出剩下的扑克牌的堆数,并且输出每一堆的牌数. #include<stdio.h> #include<iostre

ACM学习历程——UVA 127 &quot;Accordian&quot; Patience(栈;模拟)

Description  ``Accordian'' Patience  You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate n

UVA 127 &quot;Accordian&quot; Patience

题意: 按从左至右的顺序发牌,并摆成一行,发牌不要相互重叠.游戏中一旦出现任何一张牌与它左边的第一张或第三张“匹配”,即花色或点数相同,则须立即将其移动到那张牌上面.如果牌被移动后又出现了上述情况,则需再次向左移动.每叠牌只能移动最上面的一张.如果一叠牌被移空,应该立即将右边各叠整体向左移动,补上这个空隙.依次将整副牌都发完,并不断的向左合并.如果全部移动结束后整副牌都放成了一叠,则游戏胜利. 分析: 用sum表示有多少个牌挪动了,最后输出52-sum.判断是否能放到左边第三张的时候需要注意再前

UVa OJ 127 - &quot;Accordian&quot; Patience (“手风琴”纸牌)

UVa OJ 127 - "Accordian" Patience ("手风琴"纸牌) Time limit: 3.000 seconds 限时:3.000秒 Problem 问题 You are to simulate the playing of games of "Accordian" patience, the rules for which are as follows: 模拟玩一个"手风琴"纸牌游戏,规则如下: D

127 - &quot;Accordian&quot; Patience

很简单呢的一道题,定义了一个结构体数组,用vector来做为一个牌堆.将尾部作为牌堆的顶部. 要注意,当最后只剩一堆牌的时候,答案中的pile不加s #include<bits/stdc++.h> using namespace std; const int maxn = 60; int b[60]; struct pile { vector<string> a; }; int main() { ios::sync_with_stdio(false); string buf; wh

Uva 127 poj 1214 `Accordian&#39;&#39; Patience

 ``Accordian'' Patience  You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate neighbour on

``Accordian&#39;&#39; Patience UVA 127

说说: 这道题难度其实并不但,但是比较繁琐,且细节容易被忽略.先分析一下游戏规则吧,知道游戏规则之后,问题自然而然就解决了.首先放着一行52个扑克牌堆(ps:输入的时候分两行输入)开始每堆只有一张牌,然后从左到右开始判断,若一张牌和左边第一张牌或者左边第三张牌的大小或者花色相同,则将该张牌放到那一对牌之上并且要求继续向左匹配,直到不能匹配为止.若某个堆一张牌都不剩了,则该堆不存在了,也就是说如果两堆相邻,则两堆的牌数都不能为0.最后按照这个规则,直到没有牌能够移动位置.(ps:移动是指顶层牌的移

&quot;Accordian&quot; Patience UVA 127 (”手风琴“牌游戏)

"Accordian" Patience From:UVA, 127 Submit Time Limit: 3000 MS You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever th

uva ``Accordian&#39;&#39; Patience

题目如下: ``Accordian'' Patience You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate neighbour