问题描述:

有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. hibernate注解原理

    持续更新中.. hibernate注解用的是java注解,用到的是java反射机制.

  2. JSP学习笔记(1)

    JSP本质就是一个servlet,当第一次接受到客户端请求时会被编译成对应的servlet,且对应的每个servlet在容器中只要一个实例. 1.1.JSP注释 <%-- JSP注释部分 --& ...

  3. Swift语言 代码添加文本输入框 和 占位文本

    //懒加载文本输入框 private lazy var textView: UITextView = { let textView = UITextView() textView.font = UIF ...

  4. 使用 ADD-ON SDK 开发 基于 Html JQuery 和 CSS 的 firefox 插件入门教程1: 创建一个简单的 Add-on

    [本文转载自http://sixpoint.me/942/implementing-simple-addon/] 实现一个简单的插件 教程的这个部分带你使用 SDK 来实现, 运行并打包一个插件. 这 ...

  5. showModalDialog-父窗体子窗体

    showModalDialog使用例子,父窗口向子窗口传递值,子窗口设置父窗口的值,子窗口关闭的时候返回值到父窗口. farther.html --------------------------- ...

  6. jsp js java

    Java技术 J a v a是一种 简单易用. 完全面向对象. 具有平台无关性且 安全可靠的主要面向I n t e r n e t的开发工具. 自从1 9 9 5年正式问世以来,J a v a的快速发 ...

  7. ubuntu14.04使用reaver跑pin码

    今天刚说过没找到支持ubuntu14.04用reaver跑pin的旧版库文件这就有摸索到方法了... 另外安装系统ubuntu14.04以及一系列破解工具比如aircrack,minidwep等都不在 ...

  8. .net performance

    http://msdn.microsoft.com/en-us/library/ms173196.aspx http://www.zhihu.com/question/20314377 http:// ...

  9. 单片机汇编语言实现DES加密算法

    目前在金融界及非金融界的保密通信中,越来越多地用到了DES算法.DES(Data Encryption Standard)即数据加密算法,是IBM公司于 1977年研究成功并公开发表的.随着我国三金工 ...

  10. 检测IIS应用程序池对象 回收

    function RecycleYourAppPool([string] $poolName){ Import-Module WebAdministration #获取所有Application Po ...