当前位置: 首页 > news >正文

求13张扑克牌的原顺序

题目:

有一个游戏,取一个花色的所有13张扑克牌,成为一摞,按照如下的规则取牌:

(1)将最上面一张牌放到这一摞牌的最下面

(2)然后将最上面的一张牌取出以后不断重复1,2的动作,直到所有的扑克牌取完为止。

问题:如果要使得取出扑克牌的顺序为从小到大,即顺序为:A、2、3、4、5、6、7、8、9、10、J、Q、K,请使用C/C++编程求出最初扑克牌的顺序应该是什么。

解题思路:

方法一:观察这个问题,它有放牌和取牌两个过程,结束条件为所有扑克牌取完。所以我将两个过程都写成一个函数,然后放在主函数的循环中重复执行,直到满足结束条件。从正向解决这个问题,我定义了一个数组赋值1~13,这个13个数代表了我的牌在原牌堆中的顺序,那么我重复进行操作一、二后取出的序列就是牌面A~K对应在原牌堆的位置,按照这个顺序对A~K进行排序后得到的即为最初扑克牌的顺序。

操作一:记录第一个元素>>数组元素循环前移一个>>第一个元素赋给最后一个位置

操作二:记录第一个元素>>数组元素循环前移一个>>返回第一个元素并且牌堆长度-1(取牌)

方法二:我将题目中操作一理解为将整个牌堆首尾相连(一群人围成圈),操作二理解为每次都取当前牌环的第二张牌(依次进行从1开始的报数,报到2的人被淘汰),那么整个问题就可以看成一个经典的约瑟夫问题。

我有一道约瑟夫问题的代码,可以先去理解那道。

约瑟夫问题-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/a921876874/article/details/142664107?spm=1001.2014.3001.5501

程序代码:

方法一(模拟取牌过程):

#include <stdio.h>
void one_fun(int *);//操作一
int two_fun(int *);//操作二
int len = 13;//len作为全局变量传递,代表当前牌数
int main(int argc, char *argv[])
{ int i = 1;int ret;int ch2[13] = {1,2,3,4,5,6,7,8,9,10,11,12,13};//值代表在原牌堆的牌序int ch[13] = {0};//存放原牌堆的牌while(len != 0){//没有取完时重复操作一、二one_fun(ch2);ret = two_fun(ch2);//由于原数组中存的是原牌堆的牌序,所以返回值代表这次取出的牌在原牌堆的位置ch[ret-1] = i;//数组下标从0开始,ret-1得到对应位置i++; }//取出牌面从1~13,i在这里代表牌面大小printf("扑克牌最初的顺序为:\n");for(i = 0; i <13; i++){//这里13不可以写成len,len在前面循环结束后已经为零printf("%d ",ch[i]);}//输出最初的牌序puts("");return 0;
} 
void one_fun(int *p)
{int i;int c = *p;//拿第一张牌for(i = 0; i < len-1; i++){//所有牌循环前移p[i] = p[i+1];}p[len-1] = c;//将第一张牌插入牌尾
}
int two_fun(int *p)
{int i;int c = *p;//记录第一张牌for(i = 1;i <= len-1; i++){//所有牌循环前移p[i-1] = p[i];}len--;//取牌后总牌数-1return c;//取牌操作
}

 方法二(利用本质是约瑟夫问题求解):

#include <stdio.h>
int main()
{int i,j;int a[13];//存原牌堆排序int b[13];//取出的牌堆int c[13];//存原牌堆牌int count1 = 0;//判定当前位置是否需要取牌int count2 = 0;//统计取出牌数量for(i = 0;i < 13;i++){a[i] = i+1;}//赋值牌序i = 0;j = 0;while(count2 < 13){//当没有取完所有牌时循环if(a[i] != 0){count1++;}//如果没有被取过if(count1 == 2){//符合被取走条件b[j] = a[i];//记录取走的牌a[i] = 0;//标记已经被取走count1 = 0;//重置判断条件count2++;//取出牌数增加j++;}i++;//保证下一轮循环判断下一张牌if(i==13){//如果到牌尾,将判断位置重新置于牌头i = 0;}}printf("原本的排序为:\n");for(i = 0; i < 13; i++){for(j = 0; j < 13; j++){if(i+1 == b[j]){//数组b的值和i+1都代表该牌在原牌堆的顺序c[i] = j+1;//c[i]代表原牌堆的牌面大小,j+1代表顺序为b[j]牌的牌面大小printf("%d ",c[i]);}}}puts("");return 0;
}

运行结果:

1~13分别代表A、2、3、4、5、6、7、8、9、10、J、Q、K。

扑克牌最初的顺序为:
7 1 12 2 8 3 11 4 9 5 13 6 10 
原本的排序为:
7 1 12 2 8 3 11 4 9 5 13 6 10 

http://www.mrgr.cn/news/50407.html

相关文章:

  • Windows系统部署redis自启动服务
  • 【头歌平台实验】【使用Matplotlib模块进行数据可视化】【网络机器人相关法律责任】【网页抓取及信息提取】
  • 如何将 FMEA 应用于实际的产品开发项目中?
  • Spring Boot在中小型医院网站中的应用
  • 【数据处理】大数据入门
  • 自动驾驶系列—自动驾驶中的持续测试(CT):保障软件质量的关键环节
  • sql-labs靶场第十四关测试报告
  • 小心selinux对应用的影响
  • Windows 10/11电脑右键菜单过多清理方法
  • 亚信安慧AntDB数据库基于操作符的隐式转换
  • IDEA下载安装
  • 深入理解UML类图:掌握类与关系的设计奥秘
  • 节点+镜像
  • 【Linux】【命令】查找(grep/find)与统计(wc)
  • 电信卡都是有合约期吗?一般是多久?
  • Linux源码阅读: Linux内核启动的基本流程
  • 动力学控制过程
  • 花生米清洗污水处理设备核心处理方法
  • 19 Shell Script awk命令
  • 华为OD机试真题---热点网站统计