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

注意细则:如果同时有多张牌都可以移动,你应该采取的策略是移动最左边可移动的牌。当一张牌既可以移动到左边第一张,又可以移动到左边第三张时,应移动到左边第三张上面。


代码:(Accepted,0.100s)

//UVa127 - "Accordian" Patience
//Accepted 0.100s
//#define _XIENAOBAN_
#include<iostream>
#include<cstdio>
#define NUM 52
#define BIAS 1
using namespace std; struct card {
char a, b;
bool operator ==(card& that) {
return a == that.a || b == that.b;
} }; struct stack {
card st[NUM + 2], *p;
void ini() {
p = st + 1;
}
card& pop() {
if (p != st) return *(p--);
return *p;
}
card& top() {
return *p;
}
void push(card& c) {
*++p = c;
}
int size() {
return p - st;
}
bool empty() {
return p == st;
}
}cards[NUM + 3]; struct list {
stack *ls[NUM + 2];
list() {
for (int i(0);i < NUM + 1;++i)
ls[i] = cards + i;
ls[NUM + 1] = nullptr;
}
void erease(int n) {
while (ls[n] != nullptr) {
ls[n] = ls[n + 1];
++n;
}
}
stack& operator [](int i) {
if (i >= 0) return *ls[i];
return *ls[0];
}
}; int main()
{
#ifdef _XIENAOBAN_
#define gets(T) gets_s(T, 129)
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif cards[0].st[1].a = cards[0].st[1].b = 'X'; // 第0个stack的top里储存一个没用的card,使得没有一张卡片与之相等,以方便以后处理前两张左边没牌的牌;
while ((cards[1].st[1].a = getchar()) != '#') {
cards[1].st[1].b = getchar();
getchar();
for (int i(0);i < NUM + 3;++i) cards[i].ini(); // 每个stack里将都只有一张卡片,这个ini就是把top的指针指向1
for (int i(2);i < NUM + 1;++i) { // 数据全部直接作为top读取到stack里面
cards[i].top().a = getchar();
cards[i].top().b = getchar();
getchar();
}
list pile; //处理部分,直接模拟,懒得另写函数了
int num;
for (num = 2;&pile[num];) { // num从2开始,毕竟第一个数据怎么样也移动不了(接下来num再跳回1就懒得管他了)
if (pile[num].top() == pile[num - 3].top()) {
pile[num - 3].push(pile[num].pop());
if (pile[num].empty()) pile.erease(num);
num -= 3;
}
else if (pile[num].top() == pile[num - 1].top()) {
pile[num - 1].push(pile[num].pop());
if (pile[num].empty()) pile.erease(num);
--num;
}
else ++num;
}
printf("%d pile", num - 1);
if (num != 2) printf("s");
printf(" remaining:");
for (int i(1);i < num;++i) printf(" %d", pile[i].size());
puts("");
}
return 0;
}

分析:差不多又是一遍过,而且只用了0.1s,竟然挤进了UVa本题Ranking的前20,虽然题目确实很简单就是了,还是开心的不行。

我的思路是安放52个栈,直接进行模拟操作。从第二张牌开始(毕竟第一张牌不可能向左移动)往下判断,直到到达末尾。

具体流程是,若当前牌可以左移,移之,并且下一个进行判断的牌还是它(因为左侧的都是已经完成的不可能再有可移动的牌了,所以无需重新从最左侧开始检索);反之此牌没法动了,则判断下一张牌。

感觉这不能叫遍历,毕竟期间会向左移动牌,应该算是迭代吧。

要注意的是输出格式!如下图所示,

6 piles remaining: 40 8 1 1 1 1

1 pile remaining: 52

pile/piles的单复数问题。

最新文章

  1. MySQL中select * for update锁表的范围
  2. WCF的三个名称/命名空间,你是否傻傻分不清楚?
  3. 大熊君大话NodeJS之------Net模块
  4. MVC4过滤器
  5. fgetc和fputc函数
  6. iOS 开发者必知的 75 个工具(译文)
  7. 控制DIV占满屏幕
  8. MongoDB的备份(mongodump)与恢复(mongorestore)
  9. malloc()与calloc差别
  10. BZOJ 2194 [快速傅里叶变换 卷积]
  11. pat1051-1060
  12. Entity Framework Core系列之DbContext
  13. OpenWrt实现802.11s组网模式
  14. Docker中Spring boot+VueJS+MongoDB的前后端分离哲学摔跤
  15. Android TableLayout中的使用说明
  16. unicode汉字编码
  17. soj2013.Pay Back
  18. Html5和Css3扁平化风格网页
  19. Ceph rgws客户端验证
  20. Unix环境高级编程(十九)终端I/O

热门文章

  1. mysql命令参数详解
  2. bootstrap使用模板
  3. 更换gitlab公网IP,引发的故障。
  4. GDOI2014模拟pty爬山(mountain)
  5. swfobject.js加载swf,关于是否加加载完成;
  6. 《Algorithms Unlocked》读书笔记1——循环和递归
  7. Webdriver API之操作(一)
  8. 类似智能购票的demo--进入页面后默认焦点在第一个输入框,输入内容、回车、right时焦点自动跳到下一个,当跳到select时,下拉选项自动弹出,并且可以按上下键选择,选择完成后再跳到下一个。
  9. 面试题 ARC
  10. java多线程基本概述(二十)——中断