论文部分内容阅读
【摘要】文中分析了扑克原始排序与按一定规律发出扑克的顺序的相互关系,运用数据结构知识,进行了算法分析,并运用C语言编程求解。最大的特色在于将扑克问题准确、巧妙地抽象为数组问题,利用计算机模拟实现发牌过程,使得问题求解更加简便,增强了问题的可操作性。
【关键词】数据结构 循环链表 存储
Research on the playing cards
Qiao Weiping Qing Liang
【Abstract】In this article, the writer has analyzed the relation between the primordial order of the playing cards and the order of the playing cards sent according to a stated rule, analyzed the algorithm and got a solution applying the computer programming language C. The biggest character is you must abstract the playing cards problem correctly and cleverly as the array problem and then make use of the computer simulation to actualize the course of distributing the playing cards, doing which can make the problem solved easier and also has strengthened the maneuverability of the problem.
【Keywords】Data structure Circle chain list Memory
1.问题提出。编号为1,2,3,…,n的n张扑克牌按顺序叠在一起,现将牌最上面一张(编号为1)发出,将下一张(编号为2)放在这叠牌的最下面,再将下一张(编号为3)发出,依此类推,直至发完所有牌。试回答下面的问题:(1)最后一张是什么牌?特别地,当n=13,54,1000时,结果分别是什么?(2)如果想发出的牌刚好是1,2,3,…,n这样一个顺序,问原来的牌是怎样排列的?特别地,当n=13,54时,牌具体是怎样排列的?
2.问题分析与算法思想。对于问题(1),我们分析题给发牌规律发现,可等效为如下过程:
Step1:定义一个数组a[n],其数组首尾相连,形成环状,共n个元素,初始化为1,2,3,…,n;
Step2:从首位取出第一个元素,然后跳过一个非零元素取出下一个非零元素,将已被取出的元素标记其值为0;
Step3:从剩余的元素中继续跳过一个非零元素取出下一个非零元素,将已被取出的元素标记其值为0;
Step4:如此重复,直至取出最后一个非零元素;
Step5:取出的最后一个元素即为最后发出的那一张扑克牌的编号。
因此,我们解决了这样的一个从数组中取出元素的问题,就等同解决了第一个扑克问题,而这样的数组问题是可以通过C语言的编程实现的。
对于问题(2),很显然这与第一个问题发牌的过程是互逆的,我们依然把这个问题转换成数组来考虑。
Step1:定义一个数组a[n],其数组首尾相连,形成环状,共n个元素,均初始化为0;
Step2:将第一个元素赋值为1,然后跳过一个零元素为下一个零元素赋值为2;
Step3:在剩余的元素中继续跳过一个零元素为下一个零元素顺序逐次赋值为3、4、5…;
Step4:如此重复,直至赋完最后一个元素值为n;
Step5:得到的数组元素的排序即为所求的扑克原始排序。
因此,我们解决了这样的一个为数组元素赋值的问题,就等同解决了第二个扑克问题,而这样的数组问题同样是可以通过C语言的编程实现的。
3.算法流程图。
说明:问题2的算法实现与问题1互为逆过程,其算法流程图这里从略。
4.程序与运行结果。于是,根据算法流程图,我们设计了实现算法的C程序,实现了对任意数目的扑克牌按照题给规律发出的最后一张扑克牌的编号的求解,程序代码及运行结果如下:
问题(1)的C程序代码:
#include
void main()
{int i,n,j,sign,a[10000];/*sign记录跳过的位置数*/
printf("请输入扑克的最大编号:\n\n");
scanf("%d",&n);
printf("\n发牌的顺序如下:\n",n);
/*初始化数组,亦即给牌编号*/
for(i=0,j=0;i a[i]=i+1; /*编号1,2,3…,n*/
sign=1; /*初始化sign*/
/*初始化sign*/
for(i=0;;)
{
if(a[i]) sign++; /*找到下一个非零数跳过*/
if(sign==2)
{printf("%3d",a[i]); /*当找到第二个非零值时输出*/
a[i]=0; /*输出后该位置标记为0*/
sign=0; /*同时sign有从零开始计数*/
++j; /*记录输出数值的个数*/
}
if(++i==n) i=0; /*查找到末尾时返回起点*/
if(j==n-1) break; /*当所有数值全部输出时终止*/
}
/*输出最后一个数值,亦即最后一张牌*/
for(i=0;i if(a[i])
printf("\n最后一张牌是:\t%3d\n\n",a[i]);
}现仅给出n=13时的运行结果,其他结果从略:
参考文献
1 姜启源等编.大学数学实验[M].北京:清华大学出版社,2005.2
2 谭浩强编.C程序设计(第三版).北京:清华大学出版社, 2006.6
3 郑莉等编著.C++语言程序设计(第3版).北京:清华大学出版社,2006.6
【关键词】数据结构 循环链表 存储
Research on the playing cards
Qiao Weiping Qing Liang
【Abstract】In this article, the writer has analyzed the relation between the primordial order of the playing cards and the order of the playing cards sent according to a stated rule, analyzed the algorithm and got a solution applying the computer programming language C. The biggest character is you must abstract the playing cards problem correctly and cleverly as the array problem and then make use of the computer simulation to actualize the course of distributing the playing cards, doing which can make the problem solved easier and also has strengthened the maneuverability of the problem.
【Keywords】Data structure Circle chain list Memory
1.问题提出。编号为1,2,3,…,n的n张扑克牌按顺序叠在一起,现将牌最上面一张(编号为1)发出,将下一张(编号为2)放在这叠牌的最下面,再将下一张(编号为3)发出,依此类推,直至发完所有牌。试回答下面的问题:(1)最后一张是什么牌?特别地,当n=13,54,1000时,结果分别是什么?(2)如果想发出的牌刚好是1,2,3,…,n这样一个顺序,问原来的牌是怎样排列的?特别地,当n=13,54时,牌具体是怎样排列的?
2.问题分析与算法思想。对于问题(1),我们分析题给发牌规律发现,可等效为如下过程:
Step1:定义一个数组a[n],其数组首尾相连,形成环状,共n个元素,初始化为1,2,3,…,n;
Step2:从首位取出第一个元素,然后跳过一个非零元素取出下一个非零元素,将已被取出的元素标记其值为0;
Step3:从剩余的元素中继续跳过一个非零元素取出下一个非零元素,将已被取出的元素标记其值为0;
Step4:如此重复,直至取出最后一个非零元素;
Step5:取出的最后一个元素即为最后发出的那一张扑克牌的编号。
因此,我们解决了这样的一个从数组中取出元素的问题,就等同解决了第一个扑克问题,而这样的数组问题是可以通过C语言的编程实现的。
对于问题(2),很显然这与第一个问题发牌的过程是互逆的,我们依然把这个问题转换成数组来考虑。
Step1:定义一个数组a[n],其数组首尾相连,形成环状,共n个元素,均初始化为0;
Step2:将第一个元素赋值为1,然后跳过一个零元素为下一个零元素赋值为2;
Step3:在剩余的元素中继续跳过一个零元素为下一个零元素顺序逐次赋值为3、4、5…;
Step4:如此重复,直至赋完最后一个元素值为n;
Step5:得到的数组元素的排序即为所求的扑克原始排序。
因此,我们解决了这样的一个为数组元素赋值的问题,就等同解决了第二个扑克问题,而这样的数组问题同样是可以通过C语言的编程实现的。
3.算法流程图。
说明:问题2的算法实现与问题1互为逆过程,其算法流程图这里从略。
4.程序与运行结果。于是,根据算法流程图,我们设计了实现算法的C程序,实现了对任意数目的扑克牌按照题给规律发出的最后一张扑克牌的编号的求解,程序代码及运行结果如下:
问题(1)的C程序代码:
#include
void main()
{int i,n,j,sign,a[10000];/*sign记录跳过的位置数*/
printf("请输入扑克的最大编号:\n\n");
scanf("%d",&n);
printf("\n发牌的顺序如下:\n",n);
/*初始化数组,亦即给牌编号*/
for(i=0,j=0;i
sign=1; /*初始化sign*/
/*初始化sign*/
for(i=0;;)
{
if(a[i]) sign++; /*找到下一个非零数跳过*/
if(sign==2)
{printf("%3d",a[i]); /*当找到第二个非零值时输出*/
a[i]=0; /*输出后该位置标记为0*/
sign=0; /*同时sign有从零开始计数*/
++j; /*记录输出数值的个数*/
}
if(++i==n) i=0; /*查找到末尾时返回起点*/
if(j==n-1) break; /*当所有数值全部输出时终止*/
}
/*输出最后一个数值,亦即最后一张牌*/
for(i=0;i
printf("\n最后一张牌是:\t%3d\n\n",a[i]);
}现仅给出n=13时的运行结果,其他结果从略:
参考文献
1 姜启源等编.大学数学实验[M].北京:清华大学出版社,2005.2
2 谭浩强编.C程序设计(第三版).北京:清华大学出版社, 2006.6
3 郑莉等编著.C++语言程序设计(第3版).北京:清华大学出版社,2006.6