·【蓝桥】·拉马车

拉马车(我小时候管这个叫拖拉机)的游戏使用算法预测最终结果,想想还是挺有意思的~
该题可作为一道练习递归的例题~

题目来源:
青蛙跳杯子

问题描述
  小的时候,你玩过纸牌游戏吗?
  有一种叫做“拉马车”的游戏,规则很简单,却很吸引小朋友。
  其规则简述如下:
  假设参加游戏的小朋友是A和B,游戏开始的时候,他们得到的随机的纸牌序列如下:
  A方:[K, 8, X, K, A, 2, A, 9, 5, A]
  B方:[2, 7, K, 5, J, 5, Q, 6, K, 4]
  其中的X表示“10”,我们忽略了纸牌的花色。
  从A方开始,A、B双方轮流出牌。
  当轮到某一方出牌时,他从自己的纸牌队列的头部拿走一张,放到桌上,并且压在最上面一张纸牌上(如果有的话)。
  此例中,游戏过程:
  A出K,B出2,A出8,B出7,A出X,此时桌上的序列为:
  K,2,8,7,X
  当轮到B出牌时,他的牌K与桌上的纸牌序列中的K相同,则把包括K在内的以及两个K之间的纸牌都赢回来,放入自己牌的队尾。注意:为了操作方便,放入牌的顺序是与桌上的顺序相反的。
  此时,A、B双方的手里牌为:
  A方:[K, A, 2, A, 9, 5, A]
  B方:[5, J, 5, Q, 6, K, 4, K, X, 7, 8, 2, K]
  赢牌的一方继续出牌。也就是B接着出5,A出K,B出J,A出A,B出5,又赢牌了。
  5,K,J,A,5
  此时双方手里牌:
  A方:[2, A, 9, 5, A]
  B方:[Q, 6, K, 4, K, X, 7, 8, 2, K, 5, A, J, K, 5]
  注意:更多的时候赢牌的一方并不能把桌上的牌都赢走,而是拿走相同牌点及其中间的部分。但无论如何,都是赢牌的一方继续出牌,有的时候刚一出牌又赢了,也是允许的
  当某一方出掉手里最后一张牌,但无法从桌面上赢取牌时,游戏立即结束。
  对于本例的初始手牌情况下,最后A会输掉,而B最后的手里牌为:
  9K2A62KAX58K57KJ5
  本题的任务就是已知双方初始牌序,计算游戏结束时,赢的一方手里的牌序。当游戏无法结束时,输出-1。
  输入为2行,2个串,分别表示A、B双方初始手里的牌序列。
  输出为1行,1个串,表示A先出牌,最后赢的一方手里的牌序。
样例输入
96J5A898QA
6278A7Q973
样例输出
2J9A7QA6Q6889977
样例输入
25663K6X7448
J88A5KJXX45A
样例输出
6KAJ458KXAX885XJ645
数据规模和约定
  我们约定,输入的串的长度不超过30
  资源约定:
  峰值内存消耗(含虚拟机) < 256M
  CPU消耗 < 1000ms

题目分析

  1. 依次记字符串a,b,c为A方,B方,桌面上的牌
  2. A,B依次摸牌,重复以下步骤:
    若有条件拿桌面上的牌,将其逆序纳为己用;
    反之,丢掉第一张牌

***注:特别注意拿牌、丢牌是字符串的增加、删除细节

judge函数,桌面上的牌和自己第一张牌有重复,满足拿牌的条件

1
2
3
bool judge(char ch){
return c.find(ch) == string::npos;
}

~不得不说dfs代码写的冗余有点高
—————————————————完整代码—————————————————

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cstdio>

using namespace std;
string a, b, c;
bool judge(char ch){
return c.find(ch) == string::npos;
}
void solve(string &s, char ch){//满足条件,可拿牌
s += ch;
for(int i = c.size()-1; i >= 0; --i){
if(c[i] == ch)
break;
s += c[i];
}
s += ch;
c.erase(c.begin()+c.find(ch), c.end());
}
void dfs(int x){//x=0,操作a;x=1,操作b
if(x == 0){
if(judge(a[0])){ //add c 丢牌
c += a[0];
a.erase(a.begin());
if(a.empty())
return;
dfs(1);
}else{ //add a 拿牌
solve(a, a[0]);
a.erase(a.begin());
dfs(0);
}
}else{
if(judge(b[0])){ //add c 丢牌
c += b[0];
b.erase(b.begin());
if(b.empty())
return;
dfs(0);
}
else{ //add b 拿牌
solve(b, b[0]);
b.erase(b.begin());
dfs(1);
}
}
}
int main(){
cin >> a >> b;
dfs(0);
if(a.empty())
cout << b << endl;
if(b.empty())
cout << a << endl;
return 0;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!