题意: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的单复数问题。
转载于:https://www.cnblogs.com/xienaoban/p/6798066.html