模拟游戏,规则如下
把卡牌一张接一张,从左到右依次摊开,不可以重叠,每当某张卡片和左边(左边第三张)卡片匹配,
它就能放到另外一张卡片上,匹配的规则是他们有一样的级别或者花色,
在每次移动完成以后,还需要再次检查这次移动后是否会造成其他可能的移动,
只有每一叠卡片最上面那张能够移动,如果一叠牌被移空,应该立即将右边各叠整体向左移动,
补上这个空隙,依次将牌发完,并尽可能的向左合并,如果最后只剩下一叠牌,则游戏胜利

多玩几次可能会出现这样的局面,
有俩个卡片可以移动,你应该采取的策略是移动最左边的卡片
如果一张卡片能够移动到左边第一个位置和第三个位置,将它移动到第三个位置上

输入到程序的数据指出了一副牌发出的顺序,输入包括俩行,
每一行包含26个卡片,每个卡片用一个空格隔开,
输入文件的最后一行包含一个#作为它的第一个字符,
一张牌代表俩个字符单元,
第一个字符是面值(A=Ace,2-9,T=10,J=Jack,Q=Queen,K=King)
第二个字符是它的花色,(C=Clubs(梅花),D=Diamonds(钻石),H=Hearts(红心),S=Spades(黑桃))

每俩行(定义了一副52张牌)产生一个输出行,
每个输出行输出经过游戏后,剩下的叠数,每叠牌中的数目

AC代码如下,适用列表,一个Head数组

将tail指针指向数组位置绝对是噩梦

 #include <iostream>
#include<stdio.h>
using namespace std; struct Node
{
Node* next = NULL;
Node* pre = NULL;
//指向最后一个位置,不能是数组的位置
Node* tail = NULL;
char suit;
char face;
int total;
};
bool compareNode(const Node* node1, const Node* node2)
{ return (node1->face == node2->face) || (node1->suit == node2->suit);
}
/**
*
*get a head that node can link.
*if can not find,return NULL
*/
int findSuitableHead(Node* const heads, int total, Node* const node)
{
int index = -;
while (true)
{
bool fh = false;
if (total >= )
{
//可以找前面第三个
Node hNode = heads[total - ];
if (compareNode(hNode.tail, node))
{
total -= ;
index = total;
fh = true;
}
}
if (!fh && total >= )
{
//前三个位置不合适,前一个位置
Node hNode = heads[total - ];
if (compareNode(hNode.tail, node))
{
total -= ;
fh = true;
index = total;
}
}
if (!fh)
{
return index;
}
}
}
void reMegerNode(Node* const heads, int& total, int sIndex)
{
while (true)
{
bool hasResize = false;
for (int i = sIndex + ; i < total; i++)
{
int j = findSuitableHead(heads, i, (heads + i)->tail);
if (j != -)
{
//可以合并
Node* nHead = heads + j;
//这句话fb50
// Node mNode = heads[i];
Node* mNode = new Node;
*mNode = heads[i]; bool nm = heads[i].total == ? true : false;
if (nm)
{
//mNode is head
mNode->total = ;
mNode->tail = NULL;
nHead->tail->next = mNode;
mNode->pre = nHead->tail;
nHead->tail = mNode;
nHead->total++;
total--;
for (int k = i; k < total; k++)
heads[k] = heads[k + ]; Node n;
heads[total] = n;
}
else
{
//不是表头
heads[i].total--;
Node* tail = heads[i].tail;
Node* pre = tail->pre;
heads[i].tail = pre;
pre->next = NULL;
tail->pre = NULL;
nHead->tail->next = tail;
tail->pre = nHead->tail;
nHead->tail = tail;
nHead->total++;
}
sIndex = j == ? : j - ;
hasResize = true;
break;
}
}
if (!hasResize)
{
return;
}
} }
void mergeNode(Node* const heads, int& total, Node* node)
{
int sIndex = findSuitableHead(heads, total, node);
if (sIndex == -)
{
//new head
node->total = ;
heads[total] = *node;
heads[total].tail = node;
total++;
}
else
{
heads[sIndex].tail->next = node;
node->pre = heads[sIndex].tail;
heads[sIndex].tail = node;
heads[sIndex].total++;
reMegerNode(heads, total, sIndex);
}
}
void print(Node* const heads, int total)
{
if(total!=)
cout << total << " piles remaining:";
else
cout << total << " pile remaining:";
for (int i = ; i < total; i++)
{
cout << " " << heads[i].total;
}
cout << endl;
} int main()
{
//freopen("d:\\1.txt", "r", stdin);
char c1;
while (true)
{
Node* node = new Node;
cin >> c1;
if (c1 == '#')
{
return ;
}
node->face = c1;
cin >> node->suit;
int total = ;
Node heads[];
node->total = ;
heads[total++] = *node;
heads[total - ].tail = node;
for (int i = ; i < ; i++)
{
node = new Node;
cin >> node->face >> node->suit;
mergeNode(heads, total, node);
}
print(heads, total);
}
}

UVA127的更多相关文章

  1. [刷题]算法竞赛入门经典(第2版) 6-9/UVa127 - "Accordian" Patience

    题意:52张牌排一行,一旦出现任何一张牌与它左边的第一张或第三张"匹配",即花色或点数相同,则须立即将其移动到那张牌上面,将其覆盖.能执行以上移动的只有压在最上面的牌.直到最后没有 ...

  2. UVa127,"Accordian" Patience

    注意1堆的时候,pile后面没有s!!!!因为这个WA了一次,否则就1A了 犯了一个很幼稚很幼稚的错误,申请ans[]后玩了吧ans置0,结果调了好长好长时间,本来是敲完就能过的T T啊啊啊啊啊啊,一 ...

  3. UVA-127 "Accordian" Patience (模拟)

    题目大意:一种纸牌游戏,将52张扑克牌排成一列,每次操作可将一张扑克牌移到它的前一张或前面第三张上当牌的点数或花色匹配时.每次都移动最靠左的扑克牌,并且能移动三格就移动三格.求最终扑克牌状态. 题目分 ...

  4. ACM学习历程——UVA127 "Accordian" Patience(栈, 链表)

    Description  ``Accordian'' Patience  You are to simulate the playing of games of ``Accordian'' patie ...

  5. UVA-127 "Accordian" Patience(模拟)

    题目: 把52张牌从左到右排好,每张牌自成一个牌堆.当某张牌与它左边那张牌或者左边第三张牌匹配时(花色或者点数相同)时,就把这张牌移到那张牌上面. 移动之后还要查看是否可以进行其他移动.只有位于牌堆顶 ...

  6. 入门经典——基础数据结构专题(List)

    UVA127 链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  7. UVa 127 纸牌游戏(栈)

    https://vjudge.net/problem/UVA-127 题意: 按从左至右的顺序发牌,并摆成一行,发牌不要相互重叠.游戏中一旦出现任何一张牌与它左边的第一张或第三张“匹配”,即花色或点数 ...

随机推荐

  1. JavaScript 之call , apply 和prototype 介绍

    1. 前言 为什么将这三个概念放在一起说.原因是这些是会在实现js 继承会需要使用到的 2. call 和 apply call 和 apply 的作用基本类似, 都是去执行function并将这个f ...

  2. (1)json和pickle序列化模块

    json 和pickle 模块 json和pickle模块下都有4个功能 dumps  <---> loads  (序列化 <--->反序列化) dump <---> ...

  3. CTF-练习平台-Misc之 宽带信息泄露

    七.宽带信息泄露 下载文件发现是bin文件,题目又说是宽带,所以用工具RouterPassView,打开工具 打开bin文件 快捷键:Ctrl+F搜索username 找到宽带用户名了.

  4. Assert随笔

    ☆ Assert.notNull(haha, "未找到需要导入的计划1");//haha必须不能为null,if为null则抛出message的异常: Assert.hasText ...

  5. windows下配置redis

    1.首先去GitHub上下载所需文件,这里我们下载的是zip文件 https://github.com/MicrosoftArchive/redis/releases 2.解压后文件目录如下 3.启动 ...

  6. LG3898 [湖南集训]大新闻

    题意 题目描述 **记者弄了个大新闻,这个新闻是一个在 [0,n) 内等概率随机选择的整数,记其为 x.为了尽可能消除这个大新闻对公众造成的不良印象,我们需要在 [0,n)内找到某一个整数 y,使得 ...

  7. day12 python学习 装饰器

    闭包函数: 内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数#函数内部定义的函数称为内部函数 闭包函数获取网络应用 from urllib.request import url ...

  8. cmd下查看当前登陆用户

    cmd下查看当前登陆用户 终端下,自然可以用quser这个命令了.但是在其它如专业版2k下如何查看在线用户呢? C:\Documents and Settings\Administrator>n ...

  9. Jmeter之JDBC

     jdbc:mysql://ip:3306/test?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true 

  10. 【转】每天一个linux命令(25):linux文件属性详解

    原文网址:http://www.cnblogs.com/peida/archive/2012/11/23/2783762.html Linux 文件或目录的属性主要包括:文件或目录的节点.种类.权限模 ...