2019独角兽企业重金招聘Python工程师标准>>>

题意:
移牌游戏,按以下规则:
1. 从左向右, 考虑每张牌, 若某张牌与其左边第1张或左边第3张是同一个牌号或花色, 则就把这张牌移到左边的匹配牌上方, 并继续向左边移动, 直至左边第1张或第3张都不是符合的牌为止.
2. 如果同时有两张以上的牌可以移动, 则总是移动最左边的牌.
3. 如果既可以移到左边第1张也可以移到左边第3张, 则总是移到左边第3张上面.
4. 如果某一列被移为空, 则把右边的牌合并过来.
5. 每次只取一列中最顶上的牌进行比较.
当所有牌都不能移动时, 从左到右输出每一列包含的张数.

思路:
1. 使用 list 存放每一列, 再使用 vector 存放所有的列.
2. 每次比较时, 在 vector 里从左到右依次取出一列, 比较其最顶的牌与其左边第1张、第3张牌是否为同一分组,若是同一分组, 则按"题意"规则 1, 3 进行移动.
3. 注意, 当一张牌移动完毕后, 应该从它移动到的牌的下一张开始重新循环, 而不是移动时的牌的下一张, 否则无法满足"题意"中的规则 2.

要点:
1. vector 的 erase 会自动把后(右)边的元素补上来, 正好满足这里的需要.
2. list 通过 push_front, push_back, pop_front, pop_back 来操纵其首尾元素.

题目:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=103&page=show_problem&problem=63

代码:

# include <iostream>
# include <string>
# include <cstdio>
# include <cstring>
# include <vector>
# include <algorithm>
# include <cctype>
# include <iterator>
# include <assert.h>
# include <list>
using namespace std;// 1. 如果有两张牌可以移动,则总是移动最左的那张,即从左到右逐张牌进行处理
// 2. 如果一张牌 match 其左边第1张或第3张牌,就把它移过去
//    (要先移,即类似冒泡,而不是选择法),往复至不能移为止
// 3. 若同时满足两种情况,则移到最左边
// 4. match 是指两张牌在相同的 suit 或 rank
// 5. 只取第一张牌进行比较
// 6. 若出现某一列为空,则把它右边的列往左移 (vector earase 会自动做)// 判断两张牌是否 match, 即判断其对应字符是否相等
bool isMatch(const string& str1, const string& str2) {assert(str1.size() == 2 && str2.size() == 2);return (str1[0] == str2[0] || str1[1] == str2[1]);
}// 判断在 i 和 j 处的第一张牌是否 match
bool isMatch(const vector< list<string>* > cards, int i, int j) {if (!(i>=0 && i<cards.size() &&j>=0 && j<cards.size())) return false;list<string>::const_iterator itI, itJ;itI = cards[i]->begin();itJ = cards[j]->begin();return isMatch(*itI, *itJ);
}// 将 from 处的 card 移到 to 处
// 返回值表示 move 后当前是否为空
bool moveCard(vector< list<string>* >& cards, int from, int to) {list<string>* pileFrom = cards[from];list<string>* pileTo = cards[to];list<string>::iterator it = pileFrom->begin();pileTo->push_front(*it);pileFrom->pop_front();return pileFrom->empty();
}// 从 i 开始向右找到其能 match 到的点,直至最左端, 若没有,则返回 -1
int findMatch(const vector< list<string>* >& cards, int i) {if (isMatch(cards, i, i-3))  return i-3;if (isMatch(cards, i, i-1))  return i-1;return -1;
}// 处理当前所有牌
void dealCards(vector< list<string>* >& cards) {while (true) {int i=0;  bool needMove = false;while (i<cards.size()) {int to = findMatch(cards, i);bool needShrink = false;  if (to != -1) {needMove = true;needShrink = moveCard(cards, i, to);}if (needShrink) {delete cards[i];    // 先把这块的空间释放掉 // erase 会自动把后面的合并上来cards.erase(cards.begin()+i);}// 如果移动了,则从移动后的位置开始重新计算, // 这样才能保证有两个可以移动时,移动的是最左边的那个if (to != -1) {     i = to;continue;}i++;}// 如果全部都不需要 move 了,表示游戏结束if (!needMove) break;}
}int main(int argc, char const *argv[])
{#ifndef ONLINE_JUDGEfreopen("127_i.txt", "r", stdin);  freopen("127_o.txt", "w", stdout); #endifstring card;while (!cin.eof()) {cin >> card;if (card == "#") break;// vector 存放所有的牌, 每一列都用一个 list 来存放vector< list<string>* > cards;list<string>* pile;pile = new list<string>;pile->push_front(card);cards.push_back(pile);// 读入后 51 张牌for (int i=0; i<51; i++) {cin >> card;pile = new list<string>;pile->push_front(card);cards.push_back(pile);}dealCards(cards);// 注意 pile 有单复数之分// printf("%d piles remaining: ", int(cards.size()));if (cards.size() > 1) {printf("%d piles remaining:", int(cards.size()));} else {printf("%d pile remaining:", int(cards.size()));}// 注意这里的空格是打在 size 前面的,不是打在后面// 否则会报 Presentation errorfor (int i=0; i<cards.size(); i++) {cout << " " << cards[i]->size();    delete cards[i];                // 输出完了,要释放空间  }cout << endl;}return 0;
}

环境: C++ 4.5.3 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE

转载于:https://my.oschina.net/zenglingfan/blog/148410

127 - Accordian Patience相关推荐

  1. POJ1214 UVA127 Accordian Patience【vector】

    "Accordian" Patience Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1051 Accep ...

  2. UVA127 纸牌游戏 “Accordian“ Patience

    这道题是类似于一个邻接表的结构,用vector,来模拟,毕竟写那么多的链表还不会,每个排队一个,然后总的所有的牌堆的编号再送入一个vector里面,一开始我看数据很小,没有注意时间复杂度,20分钟过了 ...

  3. 紫书《算法竞赛入门经典》

    紫书<算法竞赛入门经典>题目一览 第3章 数组和字符串(例题) UVA 272 TEX Quotes UVA 10082 WERTYU UVA 401 Palindromes UVA 34 ...

  4. 提取了下刘汝佳推荐的题号...

    今天闲来没事上uva oj提取了下刘汝佳推荐的acm题号,原始数据如下: Volume 0. Getting Started    10055 - Hashmat the Brave Warrior ...

  5. UVa Online Judge 工具網站

    UVa Online Judge 工具網站 转自http://www.csie.ntnu.edu.tw/~u91029/uva.html Lucky貓的ACM園地,Lucky貓的 ACM 中譯題目 M ...

  6. 灵动ICPC冬令营基础-2

    灵动ICPC冬令营基础-2 A - Maya Calendar 题目 解析 代码 B - Diplomatic License 题目 解析 代码 C - "Accordian" P ...

  7. ICPC训练联盟2021寒假冬令营(2)

    文章目录 ICPC训练联盟2021寒假冬令营(2) [A - Maya Calendar](https://vjudge.net/problem/POJ-1008) 题目 分析 代码 [B - Dip ...

  8. Competitive Programming 3题解

    题目一览: Competitive Programming 3: The New Lower Bound of Programming Contests(1) Competitive Programm ...

  9. Competitive Programming专题题解(1)

    Competitive Programming题解 AOAPC I: Beginning Algorithm Contests 题解 CP2-1.1.1 Easy(Ad Hoc Problems) P ...

最新文章

  1. matlab 转换 tfrecord,训练数据集与TFRecord互相转换的两种方式
  2. centos 上传jar 命令_centos上快速将一个jar使用docker部署启动
  3. path manipulation怎么解决_干货!终于!解决macOS下pyenv安装python3.8.2缺少tkinter模块的问题!...
  4. Ubantu下使用vi时,方向键变字母输出、退格键无法删除字符的解决办法
  5. 高级产品经理的思维方式
  6. css3中transform属性及用法
  7. 基金销售“号”令天下,蚂蚁财富未来要颠覆东方财富?
  8. Ajax用法返回Json
  9. Win11重启快捷键是什么?
  10. 图像坐标球面投影_晶体的球面坐标与球面投影
  11. 计算机英语的四种变量,计算机英语:BASIC语言变量
  12. 【备忘】【No5】微信公众平台开发入门到实战开发视频教程(Java+PHP)
  13. python打印pdf特定页面_使用Python自由切分pdf文件提取任意页面
  14. 【LTE基础知识】GUTI(Globally Unique Temporary UE Identity)分配
  15. 史诗手册!微信小程序新手自学入门宝典!你想要的都在这里
  16. “现在的自动驾驶太保守!”看看轻舟智航联合创始人大方这篇论文怎么说
  17. 鼎信诺虚拟服务器导数,鼎信诺审计前端取数讲解.ppt
  18. shell学习四十三天----临时性文件的建立与使用
  19. unity3D游戏开发十一之物理引擎
  20. 【网络安全】渗透工程师面试题总结大全

热门文章

  1. 移动端应用类型及特点
  2. 仓储rfid文件_RFID智能仓储管理技术浅析之RFID电子标签的使用
  3. kmeans python interation flag_Python / Scipy Integration数组
  4. python输入变量_Python如何获取用户输入
  5. ARP探测目标工具arping常用命令集合大学霸IT达人
  6. Visual Studio警告IDE0006的解决办法
  7. 子域名/目录暴力工具Gobuster
  8. SQLite复杂表的更新方式
  9. 一级二级标题_考二级造价师有啥要求?
  10. 两年实现Nature和Science双发,这位电子科大博士火了