问题描述:
有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号那位。

题目分析:
这道题目是我们在日常生活中也能经常见到的一种报数小游戏。首先我们先分析一下游戏的核心——轮流报数 这个过程的本质是什么呢?我们分析一下游戏的过程。
我们先举一个实例:假如有5个人 分别为ABCDE
第一轮:A报1 B报2 C报3(被淘汰) D报1 E报2
第二轮:A报3(被淘汰)B报1 C(已被淘汰)D报2 E报3(淘汰)
第三轮:A(已被淘汰)B报1 C(已被淘汰)D报2 E(已被淘汰)
第四轮:A(已被淘汰)B报3(被淘汰)仅剩一人游戏结束 D获胜

总结一下就是:游戏开始,所有人依次报数,报到三的都退出。所有剩下的人继续报数。一轮结束后 第一个人接着上一轮继续报数,以此类推,直到只剩下一个人。

那么主要的动作有两个:

  1. 不断重复地1~3报数 但要跳过已被淘汰的人 且 一轮结束后 继续接着上一轮的结尾的数字
  2. 将报到3的人移出

那么如何用C语言实现这两点呢?
第二个很好解决 我们就用最简单的建立对应长度的数组 用1表示仍在场上 0表示已被淘汰。
第一个过程想要用C语言来实现就要模拟出不断1~3的循环 而且还能够不间断的在不同轮间衔接。
这样乍一看没有任何思路。那么怎么样能将问题简化一下,更加直观的表达出来呢?

1~3循环报数,报到3的淘汰的本质和从1开始报数,报到三的倍数淘汰的本质是一样的:
1 2 3(淘汰)1 2 3(淘汰)1 2 3(淘汰)
1 2 3(淘汰)4 5 6(淘汰)7 8 9(淘汰)
而且这样顺序的继续也够方便轮与轮之间的衔接 也就是不需要记住上一轮最后一个人报的是什么数字,继续一直向下报即可。

到这里 这道题的大体思路便清晰了,只要将已被淘汰的跳过等几个细节实现一下即可实现这道题目。

下面是展示版程序的代码:可以显示每一轮的具体情况(谁在报数 谁被淘汰)如不需要 将printf去掉即可。

在解决这样较复杂的问题时,先把程序写成这种能够展示过程的样子,个人认为更有利于debug和看出自己考虑不足之处。

#include<stdio.h>
int main()
{int a[120]={0}; //建立数组int i,n,k,j,final_num,sum;printf("Please enter n(<120):"); //确定参与人数 这里图方便就直接将数组定为了120人以下 也可用动态数组解决scanf("%d",&n); //n表示参与的总数sum=n;//sum为在场总数for(i=0;i<n;i++) a[i]=1; //将所有参赛选手的数值设为1for(k=0,i=1;;k++) //每一轮的循环 用k表示第几位选手 i表示报的数{printf("\n");printf("No.%d now is %d",k+1,i);if(k==n-1 && sum==1)  {printf("\n***Winner has been produced***\n"); break;} //结束循环的条件:在场仅为一人 即sum==1 前面加上k==n-1是为了最后一轮也能完整展示if(a[k]==0 && k==n-1) {k=-1; printf(" \nEnd of the Round \nLeft:%d\n",sum); continue;} //一轮循环结束的标志(最后一个已被淘汰)if(a[k]==0) {printf(" skip"); sum——; continue;} //被跳过:人被跳过 循环也跳过if(i%3==0)  {a[k]=0; printf(" out");}//报到3的被淘汰else printf(" valid");if(k==n-1)  {k=-1; printf(" \nEnd of the Round \nLeft:%d\n",sum);//一轮循环结束的标志}i=i+1; //每个人报的数字递增}for(i=0;i<=n;i++) //找到数组中唯一的1 即获胜者{if(a[i]==1)final_num=i+1;}printf("\n");printf("The winner is No.%d\n",final_num);
}

当总数为7时 程序运算的内容应该如下:

Please enter n(<120):7No.1 now is 1 valid
No.2 now is 2 valid
No.3 now is 3 out
No.4 now is 4 valid
No.5 now is 5 valid
No.6 now is 6 out
No.7 now is 7 valid
End of the Round
Left:5No.1 now is 8 valid
No.2 now is 9 out
No.3 now is 10 skip
No.4 now is 10 valid
No.5 now is 11 valid
No.6 now is 12 skip
No.7 now is 12 out
End of the Round
Left:3No.1 now is 13 valid
No.2 now is 14 skip
No.3 now is 14 skip
No.4 now is 14 valid
No.5 now is 15 out
No.6 now is 16 skip
No.7 now is 16
End of the Round
Left:2No.1 now is 16 valid
No.2 now is 17 skip
No.3 now is 17 skip
No.4 now is 17 valid
No.5 now is 18 skip
No.6 now is 18 skip
No.7 now is 18
End of the Round
Left:2No.1 now is 18 out
No.2 now is 19 skip
No.3 now is 19 skip
No.4 now is 19 valid
No.5 now is 20 skip
No.6 now is 20 skip
No.7 now is 20
***Winner has been produced***The winner is No.4

这种方法只是很简单的一种思路,程序也写的不是很有条理,有很多更好的实现方式,因为这种较为简洁易懂,所以展示在这里。

转圈报数问题(C语言):有n个人围成一圈,顺序排号……相关推荐

  1. 题目:有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位. 提示:用数组完成

    题目:有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位. 提示:用数组完成 #include <stdio.h> in ...

  2. c/c++ 有n个人围成一圈, 顺序排号。从第1个人开始报数(从1~3报数), 凡报到3的人退出圈子, 问最后留下的人原来排在第几号。

    解题思路的重要性显现出来了 比如这个题 n个人肯定是要用数组 毋庸置疑 那么报数怎么实现呢 可以设置一个循环变量 让他从0开始循环 当等于3 的时候 就归零 还有 n个人 肯定需要很多圈报数 这个很多 ...

  3. 有n个人围成一圈 顺序排号 java_java有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出...

    public class Test { public static void main(String[] args) { // 测试数据 ArrayList list = new ArrayList( ...

  4. 当当笔试题(有n个人成一圈,顺序排号(编号为1到n),从第一个人开始报数1到3报数),凡报到3的人出圈子,从下个人开始继续报数,直到最后一个人,问最后留下在是第几号?)

    -举例 12345678 第一次3走,第二次6走,第三次1走 import java.util.ArrayList; import java.util.Scanner;public class dan ...

  5. c语言有n个人围成一圈用指针,C语言 有n个人围成一圈,按顺序从1到n编号.从第一个人开始报数,报数3的人退出圈子...

    来源:学生作业帮 编辑:作业帮 分类:综合作业 时间:2021/05/20 00:22:21 C语言 有n个人围成一圈,按顺序从1到n编号.从第一个人开始报数,报数3的人退出圈子 有n个人围成一圈,按 ...

  6. c语言】13个人围成一圈,从第1个人开始顺序报号1,2,3.凡报到3者退出圈子。找出最后留在圈子中的人原来的序号

    题目(摘自谭浩强的C语言):有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那个人. 解法思路:首先不要将思维局限在一圈人,可以先将n个 ...

  7. 题目98-3:围成一圈数三报数且出列——假设有10个人围成一圈,从1开始报数,数到3的人,让他出列,下一个人重新从1开始报数,数到3的人,让他出列……以此类推,把依次出列的9个人的编号打印出来

    题目转载:http://python.wzms.com/s/1/103 题目描述: n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再 ...

  8. 数据结构课程(一)报数问题:有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……

    游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1.若一个小朋友报的数为k的倍数或其末位数(即数的个位)为k,则该小朋友被淘汰出局,不再参加以后的报数.当游戏中只剩下 ...

  9. c语言有n个人围成一圈用指针,c语言编写n个人围成一圈,按1、2、3报数,报到3的人退出,求最后留在圈中的人是最初n个人中的第几个(用指针实现)...

    以前做过的,贴一个给你,人数和报的数都可以输入的 #include #include //应用函数调用来实现 void Fun_Kill(int *pa,int n,int m) { for(int ...

  10. c语言约瑟夫环问题,C++_详解约瑟夫环问题及其相关的C语言算法实现,约瑟夫环问题 N个人围成一圈 - phpStudy...

    详解约瑟夫环问题及其相关的C语言算法实现 约瑟夫环问题 N个人围成一圈顺序编号,从1号开始按1.2.3......顺序报数,报p者退出圈外,其余的人再从1.2.3开始报数,报p的人再退出圈外,以此类推 ...

最新文章

  1. 【怎样写代码】函数式编程 -- Lambda表达式(三):LINQ初步
  2. GoCD notes
  3. 怎么查看电脑是不是禁ping_怎么查看电脑内存的大小,找回丢失的内存,电脑小技巧...
  4. 95-40-014-生产者-KafkaProducer
  5. 手机端java编辑器验证正确_java – 使用编辑器验证表的单元格
  6. BZOJ 3190: [JLOI2013]赛车
  7. 我的团长我的团第二十七集
  8. 分位数(理解层面解答)
  9. 设置电子围栏 高德地图_Android 高德地图的使用, 根据手势拖动绘制电子围栏
  10. python 如何将视频文件的语音转换为文字
  11. 百度地图使用,以及一些api
  12. 夏天宝宝晚上睡觉不踏实怎么办?
  13. 听说写面经能赞RP·······
  14. 计算机的配置是指什么,现在电脑主流配置是什么?
  15. 从实验室研发到大规模生产 纳晶科技量子点技术商用多点开花
  16. CortexM3,CortexM4存储器映像
  17. C语言第十二课:编写扫雷游戏(综合练习2)
  18. C语言《位段结构体、联合体》
  19. 乐忧商城项目总结-1
  20. linux:置之死地而后生,一次系统急救后的经验总结

热门文章

  1. 阿里云突发性能实例t5详解
  2. matlab 多个矩阵相乘,两矩阵相乘
  3. 题目 2942: 机器翻译 C语言
  4. Windows服务简单开发
  5. 小县城水果店经营技巧,夫妻水果店经营技巧
  6. java统计文章中单词出现的次数
  7. 教你如何从容面对劳动仲裁
  8. 【Atlas 800-3000/3010 04】BIOS/IBMC/CPLD升级指导
  9. ubuntu、windows双系统设置默认启动项(图文教程超详细)
  10. N/A,NG,NV是什么意思