您的位置:首页 > 汽车 > 时评 > 免费的app源码网_湖南企业建站系统信息_海阳seo排名_网站搜索排名靠前

免费的app源码网_湖南企业建站系统信息_海阳seo排名_网站搜索排名靠前

2025/1/8 6:14:33 来源:https://blog.csdn.net/qq_52291558/article/details/144247249  浏览:    关键词:免费的app源码网_湖南企业建站系统信息_海阳seo排名_网站搜索排名靠前
免费的app源码网_湖南企业建站系统信息_海阳seo排名_网站搜索排名靠前

拉马车游戏规则及实现

  • 题目描述
  • 用C++写的答案:
  • 补充:字符串查找函数 std::string::find

题目描述

小时候,我们可能玩过一种叫做“拉马车”的纸牌游戏。这个游戏规则简单,却非常吸引小朋友。

游戏规则简述

假设有两个小朋友,分别是 A 和 B。游戏开始时,他们各自持有一组随机的纸牌序列。游戏从 A 方开始,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”,我们忽略纸牌的花色。

出牌规则

  1. 当轮到某一方出牌时,他从自己的纸牌队列的头部拿走一张,放到桌上,并且压在最上面一张纸牌上(如果有的话)。
  2. 如果出的牌与桌上已有的牌相同,那么可以将包括这张牌在内的,以及两张相同牌之间的所有纸牌赢回,放入自己牌的队尾。放入牌的顺序是与桌上的顺序相反的。
  3. 赢牌的一方继续出牌。
  4. 当某一方出掉手里最后一张牌,但无法从桌面上赢取牌时,游戏结束。

示例游戏过程

  1. A 出 K, B 出 2, A 出 8, B 出 7, A 出 X, 此时桌上的序列为: K, 2, 8, 7, X
  2. B 出 K,与桌上的 K 相同,赢回 K, 2, 8, 7, X,此时双方手里牌为:
    • A 方: [K, A, 2, A, 9, 5, A]
    • B 方: [5, J, 5, Q, 6, K, 4, K, X, 7, 8, 2, K]
  3. B 出 5, A 出 K, B 出 J, A 出 A, B 出 5 赢牌,桌上序列为: 5, K, J, A, 5
  4. 最后双方手里牌为:
    • A 方: [2, A, 9, 5, A]
    • B 方: [Q, 6, K, 4, K, X, 7, 8, 2, K, 5, A, J, K, 5]

输入输出描述

输入描述

输入为两行,两个字符串,分别表示 A、B 双方初始手里的牌序列。输入的字符串长度不超过 30。

输出描述

输出为一行,一个字符串,表示 A 先出牌,最后赢的一方手里的牌序。如果游戏无法结束,输出 -1

输入输出样例

输入

96J5A898QA
6278A7Q973

输出

2J9A7QA6Q6889977

这个输出表示在游戏结束时,B 方手里的牌序为 2J9A7QA6Q6889977

用C++写的答案:

出牌操作频繁设置函数op
op函数步骤:
1.设置结束条件,玩家的牌长度=0
2.设置赢牌标识符=true
3.取玩家的第一张牌
4.根据是否赢牌,选择不同操作

如果出的牌在出牌串里有,即赢牌了,则

    • 1.添加出的牌到自己的末尾
    • 2.把出牌串中从下标为0到出牌字符的下标i的牌都放到自己的末尾
    • 3.从出牌串中移除那些赢的牌

如果没有赢牌
1.把出的牌放到z串的开头
2.设置赢牌标识符=false

主函数:
1.输入两个串A,B
2.设置A,B赢牌的标识符
无限循环游戏:
3.如果A赢牌了,则
1.A出牌,并用flagA记录A是否赢牌
2.设置结束条件,A长度=0,输出B串
3.设置flagB!=flagA,让两者不冲突

B赢牌相同操作

#include <iostream>//C++都需要导入的库
#include <string>//因为会用到字符串操作函数,导入string库
using namespace std; //用名字空间避免同名函数误用
string A,B,C;//声明三个字符串A,B,C分别放A的牌,B的牌,桌上的牌/*** 函数用于处理玩家出牌的逻辑* @param x 正在操作的玩家手中的牌* @param z 桌面上的牌* @return 操作是否成功,如果成功则返回true,表示牌被成功放置或赢取,否则返回false*/
bool op(string &x, string &z) {
//bool返回true表示牌成功放置,如果没有牌,返回false
//string x表示玩家目前要出的牌,加&表示需要对原字符串进行操作
//string z表示目前桌面上出掉的牌,因为出牌和赢牌,桌面上出的牌会发生改变,所以也加&//先设置结束条件// 如果玩家手中没有牌,即字符串长度为0,则无法出牌,返回falseif (x.length() == 0) return false;// ans来标记出牌操作是否成功,初始化操作成功的标志为truebool ans = true;//要出牌,先获取玩家手中最顶端的牌char front = x[0];// 在桌面上的牌即z字符串 中查找是否有与 玩家即将出的牌相同的牌long i=z.find(front);// 看已经出的牌z中如果有玩家要出的牌,那么玩家赢牌,赢牌条件if(i!=string::npos) { //如果i不等于 没有找到返回的string::npos(这里没有前面的std,是因为前面using namespace std)//- A 方: `[K, 8, X, K, A, 2, A, 9, 5, A]`// B 方: `[2, 7, K, 5, J, 5, Q, 6, K, 4]`
//例:A 出 K, B 出 2, A 出 8, B 出 7, A 出 X,,此时桌上的序列为: ‘X,7,8,2,K’//B 出 K,与桌上的 K 相同,即赢牌//1.把要出的牌放在自己牌的末尾,即B=[ 5, J, 5, Q, 6, K, 4,K]x.insert(x.end(), front);// 将玩家手中的这张牌添加到自己牌的末尾
//字符串插入insert,位置x.end()在x串的最后,牌为front//2.把出牌序列‘X,7,8,2,K’中的从下标为0开始到找到K的下标的牌从x串的末尾放入X中,赢回 `K, 2, 8, 7, X`,倒着放进去,此时双方手里牌为:// - A 方: `[K, A, 2, A, 9, 5, A]`//- B 方: `[5, J, 5, Q, 6, K, 4, K, X, 7, 8, 2, K]`// 将桌面上从0到找到的相同牌之间的所有牌添加到玩家牌的末尾  
//因为每次出牌都放在出牌串z的开头,所以赢牌是从下标为0开始到找到的子字符的下标for (int j = 0; j <= i; ++j) {x.insert(x.end(), z[j]);}// 3.从桌面上移除这些牌z.erase(0, i + 1); //移除函数,0表示开始位置,i+1表示要移除的个数,因为0-i有i+1个字符} else {// 如果没有找到相同的牌,将这张牌放在桌面上//在z串的开始放入玩家要出的牌,即出的每张牌都是放在出牌串z的开头z.insert(z.begin(), front);// 操作不成功,设置标志为false,没有赢牌ans = false;}// 从玩家手中移除已经出掉的牌,即在x串开头的牌x.erase(x.begin());//赢牌同样需要删掉第一张牌,因为赢牌后第一张牌已经收回x串中,此时的第一张牌应该已经出掉了并赢回牌,不是有效牌了,需要删掉// 返回操作是否成功的标志,表示是否赢牌return ans;
}// 主函数入口
int main(int argc, const char *argv[]) {//常用写法// 从标准输入读取玩家A和B的牌cin >> A >> B;// 初始化标志,表示玩家A能出牌bool flagA = true; // 初始化标志,表示玩家B能出牌,初始为false,因为游戏从玩家A开始bool flagB = false; // 使用无限循环来持续游戏,直到游戏结束while (1) {// 如果玩家A能出牌if (flagA) {// 调用op函数处理玩家A的出牌逻辑,A出牌,C是出牌字符串//如果A赢牌了,返回true,赢牌的继续出//如果A没有赢牌,返回flaseflagA = op(A, C);// 如果玩家A没有牌了,输出玩家B的牌,游戏结束if (A.length() == 0) {cout << B << endl;break;}// 设置玩家B为下一个出牌的玩家//如果A赢牌了,flagA=true,那B还是不能出牌。flagB=false//如果A没有赢牌,flagA=false,那B可以出牌了,flagB=trueflagB = !flagA;}// 如果玩家B能出牌if (flagB) {// 调用op函数处理玩家B的出牌逻辑flagB = op(B, C);// 如果玩家B没有牌了,输出玩家A的牌,游戏结束if (B.length() == 0) {cout << A << endl;break;}// 设置玩家A为下一个出牌的玩家flagA = !flagB;}}// 程序结束,返回0return 0;
}

我写的C语言代码:
问题:
1.如果是频繁的操作用函数写
2.如果涉及标识符,多个最好设置对应的标识符
3.会无限循环的写while(1)
4.逻辑没弄清楚,赢牌后原本出的牌也一样放到末尾


#include <stdio.h>
#include <stdlib.h>int main(int argc, char *argv[])
{//输入A,B的初始牌序char A[100],B[100];char chupai[300]=0;//错误: 出牌队列里面的数应该初始化为0,因为出牌队列不像A,B队列会直接输入一串字符int a,b=-1;int flag=0;//设置队列存储目前的已经出的排序int top=0,rear=0;//输入一串字符%sscanf("%s",A);scanf("%s",B);//注意:scanf输入两个字符串,用空格隔开即可//A,B轮流出牌,放入队列中//for(int i=0;i<200;i++)//{//错误;一直循环,用while即可while(1){//出牌是把出牌方的队列头部牌拿出一张 放入队列中//赢牌的一方继续出牌if(flag==0){//A赢//出牌操作频繁,可以设置函数写a++;//A出牌chupai[rear]=A[a];//把出的牌放入队列中rear++;b++;//B出牌flag=1;//表示B现在出牌//注意:flag设置有问题,一次来回是A,B的话,那只有B赢了,flag才可以=1chupai[rear]=B[b];//把B出的牌放入队列中rear++} else{b++;//B出牌flag=1;//表示B现在出牌chupai[rear]=B[b];//把B出的牌放入队列中rear++;a++;//A出牌chupai[rear]=A[a];//把出的牌放入队列中rear++;}for(int j=0;j<rear+1;j++)//如果出现有牌跟 已经出的纸牌序列其中一张牌相同,则把包括K在内及两个数之间的纸牌都拿回来逆序放入队尾{if(chupai[rear]==chupai[j]){for(int g=rear;g<=j;g++){if(flag==0)//A赢{a++;//把队列中的牌放入A中A[a]=chupai[g];}else{b++;//把队列中的牌放入A中B[b]=chupai[g];}}}}// if(a==-1)// {//  puts(B);//输出 计算游戏结束时,赢的一方手里的牌序//  }//  if(b==-1)// {//   puts(A);//   }//注意:对测字符串长度的函数不熟//可以用字符长度来看字符是否为空}return -1;
}

补充:字符串查找函数

命名空间里的string类的find方法
**用处:**找子字符串在字符串中的位置(下标从0开始)

  • 找到子字符串:返回子字符串在字符串中的位置
  • 没找到子字符串:返回 std::string::npos(一般用long类型)

例:

z="Hellow";
front="l";
z.find(front);//在Hellow找到l,下标从0开始,在下标2处找到“l”,返回2front="f";//在Hellow里找不到f,返回std::string::npos
z.find(front);

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com