问题描述:

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

分析:

首先由用户输入人数n,然后对这n个人进行编号【因为如果不编号的话,我们就不能知道最后是哪位童鞋留下来了:)】

然后就开始了一圈一圈的循环,不断形成新的圈子,不断有人被淘汰,那么循环到什么时候截止呢?对只剩最后一个人,也就是说淘汰n-1了个人的时候,这个时候停止循环。

在实际情况中,应该是这n个人一开始围成了一个大圈子,然后随着不断的淘汰,圈子不断减小,最后剩下的那个人的一开始的编号就是我们要的结果。

我在用数组来表示这些人,因为进行了初始化,所以数组中元素的值都是原来的编号,因此我们只需要将被淘汰的人对应的数组元素的值设置为0即可。然后随着不断的循环,最后只剩下一个值不为0的数组元素,这个元素就是我们要的结果。

程序代码:

#include<iostream>
#define MAXNUM 100
using namespace std;
int main()
{
int a[MAXNUM];
int n=0; //n表示一共多少人
int m=0; //m表示被淘汰的人数
int i=1; //每轮循环中的计数器
int k=0; //用来表示报数的数
int j=0; //用于循环的计数器
cout<<"请输入总人数:";
cin>>n;
//对数据进行初始化操作,给每个人进行编号
for(j=1;j<=n;j++)
{
a[j]=j;
}
//通过循环不断淘汰人,直到最后只剩下一个人
while(m < n-1)
{
if(a[i]!=0) //判断该人是否已经淘汰
{
k++;
}
if(k == 3)
{
a[i]=0; //淘汰报数为3的人(即将其值设置为0)
k=0; //将k置为0,重新报数
m++; //对淘汰人数进行计数
}
i++; //对下一个人进行判断
if(i == n+1) //到了圈子的末尾出处,下一个位置将是圈子的开始
{
i=1; //将下一个人置为 1(圈子的开始位置 )
}
}
for(j=1;j<=n;j++)
{
if(a[j]!=0)
{
cout<<"\n最后剩下的人原来的编号为:"<<a[j]<<" 的人\n"<<endl;
}
}
return 0;
}

运行界面:

延伸思考:

将用于淘汰的数字设置为变量:

上面的题目中人数n是一个变量,但是数到3就淘汰,这个数组是确定的,我们想要这个用于淘汰的数组t也作为变量,要怎么修改呢?

其实不用太大的修改,只需要设置一个变量,并由用户输入数据完成初始化,然后用来作为淘汰的数字,程序代码如下:

#include<iostream>
#define MAXNUM 100
using namespace std;
int main()
{
int a[MAXNUM];
int n=0; //n表示一共多少人
int m=0; //m表示被淘汰的人数
int i=1; //每轮循环中的计数器
int k=0; //用来表示报数的数
int j=0; //用于循环的计数器
int t=0; //用于淘汰的数字变量
cout<<"请输入总人数n:";
cin>>n;
cout<<"请输入用于淘汰的数字t:";
cin>>t;
//对数据进行初始化操作,给每个人进行编号
for(j=1;j<=n;j++)
{
a[j]=j;
}
//通过循环不断淘汰人,直到最后只剩下一个人
while(m < n-1)
{
if(a[i]!=0) //判断该人是否已经淘汰
{
k++;
}
if(k == t)
{
a[i]=0; //淘汰报数为3的人(即将其值设置为0)
k=0; //将k置为0,重新报数
m++; //对淘汰人数进行计数
}
i++; //对下一个人进行判断
if(i == n+1) //到了圈子的末尾出,下一个位置将是圈子的开始
{
i=1; //将下一个人置为 1(圈子的开始位置 )
}
}
for(j=1;j<=n;j++)
{
if(a[j]!=0)
{
cout<<"\n最后剩下的人原来的编号为:"<<a[j]<<" 的人\n"<<endl;
}
}
return 0;
}

程序运行界面:

使用单链表解决该问题

这个问题中的n虽然看起来是变量,但是我们通过代码可以看出来,它其实是有一个上线MAXNUM的,也就是当用户输入的n大于MAXNUM的时候就会出错。

那么,我们应如何写出真正意义上的可以让用户输入一个不受到限制的变量呢(实际上无论如何都收到数据类类型长度的限制的=.=)?

并且,当n很大的时候,我们就需要在内存中开辟一块连续的内存空间,在内存比较小的时候,这样做有可能无法分配内存,而单链表即满足了逻辑上的连续,而物理上却可以是不连续的。

(关于C++中的单链表,如果不是很明白可以看看这篇文章:C++中单链表的建立和操作

示例代码如下:

#include<iostream>
using namespace std;
struct Node
{
int num;
Node *next;
};
Node * Add(Node *head,int i)
{
Node *node,*htemp;
if(!(node = new Node))
{
cout<<"分配内存失败!"<<endl; //分配内存失败
return NULL;
}
else
{
node->num=i; //保存结点数据
node->next = NULL; //设置结点指针为空,即作为表尾
if(head == NULL) //当链表是空表的时候
{
head = node;
return head;
}
htemp = head;
while(htemp->next != NULL) //查找链表的末尾
{
htemp = htemp->next;
}
htemp->next = node;
return head;
} }
Node *FindNodeNum(Node *head,int k)
{
Node *htemp;
int i = 1;
htemp = head; //保存链表头指针
for(i = 1;i<k&&htemp;i++) //找到该结点
{
htemp = htemp->next;
}
return htemp; //返回指向第k个结点的指针
}
int main()
{
int n=0; //n表示一共多少人
int m=0; //m表示被淘汰的人数
int i=1; //每轮循环中的计数器
int k=0; //用来表示报数的数
int j=0; //用于循环的计数器
int t=0; //用于淘汰的数字变量
cout<<"请输入总人数n:";
cin>>n;
cout<<"请输入用于淘汰的数字t:";
cin>>t;
//对数据进行初始化操作,给每个人进行编号
Node *head=NULL;
for(j=1;j<=n;j++)
{
head=Add(head,j);
}
Node *nodeData;
//通过循环不断淘汰人,直到最后只剩下一个人
while(m < n-1)
{
nodeData=FindNodeNum(head,i);
if(nodeData->num!=0) //判断该人是否已经淘汰
{
k++;
}
if(k == t)
{
nodeData->num=0; //淘汰报数为3的人(即将其值设置为0)
k=0; //将k置为0,重新报数
m++; //对淘汰人数进行计数
}
i++; //对下一个人进行判断
if(i == n+1) //到了圈子的末尾出,下一个位置将是圈子的开始
{
i=1; //将下一个人置为 1(圈子的开始位置 )
}
}
for(j=1;j<=n;j++)
{
nodeData=FindNodeNum(head,j);
if(nodeData->num!=0)
{
cout<<"\n最后剩下的人原来的编号为:"<<nodeData->num<<" 的人\n"<<endl;
}
}
return 0;
}

运行界面:

C++经典题目:有n个人围成一圈,顺序排号,然后数数进行淘汰的解法和一些思考的更多相关文章

  1. 【转】约瑟夫环算法---------题目:有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位.

    提示:用环形链表实现 对于这个题目其实就是用c语言的循环链表实现一个约瑟夫环.我们可以定义一个循环链表,将这n个人加入到链表中,然后定义三个节点指针在链表上循环,移动跨度为3,利用链表的循环功能每次删 ...

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

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

  3. 某厂java算法题实现及改进【有n个人成一圈,顺序排号(编号为1到n),从第一个人开始报数1到3报数】

    一.第一种实现: 实现比较简单,直接贴现成的代码了,第一种实现: /** * 总人数 * * @param d */ private static void sortQuerry1(int d) { ...

  4. 经典算法:n个人围成一圈,报m的离开,最后剩下谁?

    public int remainPersonNumber(int n, int m) { //输入不合法 if(n < 1 || m < 1) return -1; //初始化,存入Li ...

  5. n人围成一圈报数

    题目:有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位 思路:用一个数组存这n个人,里面的初始状态全设为1,表示都还在圈子里面. ...

  6. java解答:有17个人围成一圈(编号0~16),从第0号的人开始从1报数,凡报到3的倍数的人离开圈子,然后再数下去,直到最后只剩下一个人为止,问此人原来的位置是多少号?

    package ttt; import java.util.HashMap; import java.util.Map.Entry; /** * 有17个人围成一圈(编号0~16),从第0号的人开始从 ...

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

    首先,我最大的学习来源不是百度而是我群友~~在这里表白一波我热爱学习的群友们!然后今天群里突然有人提出了题目的这个问题:有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3的人退出 ...

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

    1 /*37 [程序 37 报数] 2 题目:有 n 个人围成一圈,顺序排号.从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子, 3 问最后留下的是原来第几号的那位. 4 */ 5 ...

  9. C语言——N个人围成一圈报数淘汰问题

    <一>问题描述: 有17个人围成一圈(编号为0-16),从第 0号的人开始从 1报数, 凡报到 3的倍数的人离开圈子,然后再数下去,直到最后只剩下一个人为止. 问此人原来的位置是多少号? ...

随机推荐

  1. 大型系统开发sql优化总结(转)

    Problem Description: 1.每个表的结构及主键索引情况 2.每个表的count(*)记录是多少 3.对于创建索引的列,索引的类型是什么?count(distinct indexcol ...

  2. SQL 无法打开物理文件 XXX.mdf",操作系统错误 5:"5(拒绝访问。)"

    用T-SQL命令附加数据库时,出现如下异常信息: 无法打开物理文件 XXX.mdf".操作系统错误 5:"5(拒绝访问.)". (Microsoft SQL Server ...

  3. SQL server概述

    sqlserver中包含的对象: 数据库.事务日志.索引.文件组.数据库关系图.视图.存储过程.用户自定义函数.用户.角色.程序集.表.报表.全文目录.用户自定义数据类型 数据库实际上是最高层对象,其 ...

  4. CSS块级元素与行级元素(转载)

    块元素一般都从新行开始,它可以容纳内联元素和其他块元素,常见块元素是段落标签'P".“form"这个块元素比较特殊,它只能用来容纳其他块元素. 如果没有css的作用,块元素会顺序以 ...

  5. 监听tomcat服务器启动/关闭并从配置文件中读取参数进行初始化

    监听tomcat服务器启动/关闭很简单(2步): 1. 建立一个类实现ServletContextListener接口,重写其中的方法(contextDestroyed和contextInitiali ...

  6. 【转】C++箴言:理解typename的两个含义

    [转载]http://dev.yesky.com/13/2221013.shtml 问题:在下面的 template declarations(模板声明)中 class 和 typename 有什么不 ...

  7. Linux 从 sar 到 sar2html 的认识

    这些变形的工具.诸如:淘宝的Tsar.ksar.sar2html....等.都是通过抓取 sar的数据   所以在最终呈现的数据上变化不大.只是展现的手段和效果不一样而已      sar 是帮助我们 ...

  8. phpcms v9联动菜单实现筛选

    <!--初始化init--> {php $theurl = "index.php?m=content&c=index&a=lists&catid=$cat ...

  9. 微软office MIME类型

      后缀 MIME 類型 .docx application/vnd.openxmlformats-officedocument.wordprocessingml.document .docm app ...

  10. 文成小盆友python-num17 - django基础

    一.首先了解web应用的本质 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 下面利用socket实现一个简单的web框架: #!/usr/b ...