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

作者&投稿:柘秒 (若有异议请与网页底部的电邮联系)

这是约瑟夫环的数学解法(迭代法)的公式,我们可以这样理解

把n个人想成标号从0开始到n-1的n个人,报到3的人退出圈子,

那么退出圈子的人在0到n-1的标号为(k+3)%n(其中k为n-1个人时退出圈子的人的标号)

因为有一个人退出了圈子,所以还剩下n-1个人,我们对剩下的人重新从0到n-2编号,

同样有公式(k1+3)%n(其中k1为n-2个人时退出圈子的人的标号)得出n-1个人时退出圈子人的标号,

以此类推直到n等于1时kn-1=0也就是1个人时留下的就是标号为0的人

以此有递推公式f(1)=0,f(i)=(f(i-1)+3)%i f(i)为第i次退出圈子的人

我们用for循环从2个人时开始反推,经过n-1次迭代,去除退出圈子的人,

从而可以得到n个人时最后一个退出的人的标号为几,也就是最后留下的人的标号是几,

因为我们每次标号都是从0开始所以最后退出的人的实际编号=标号+1.

有了上述分析我们就不难得出程序(见图)



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

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

用数组模拟这n个人,用num来记他们的报数。当num=0时表示数组对应下标的人退出圈子,循环,最后留下来的人的号数就是数组中不为零的下标。
/*用数组模拟这n个人,用num来记他们的报数*/
#include
using namespace std;
int func(int n)
{
int residue = n;//表示剩余人数
int num = 0;//用num来模拟报数
int i = 0;//数组下标
int re_turn;//保存最后剩下的人的下标
int *a = new int[n];//new一个n个元素的数组空间
for (int i = 0; i < n; i++)
{
a[i] = 1;//首先初始化数组全为1表示存活
}
while (residue != 1)//当剩余人数还不为1
{
if (a[i] == 1)
{
num++;//实现模拟报数
}
if (num == 3)//当报到3时
{
a[i] = 0;//0表示退出
num = 0;//num重新置零
residue--;//剩余人数-1
}
i++;
if (i == n)//这里实现能够循环报数
{
i = 0;
}
}
for (int i = 0; i < n; i++)//这里来确定最后剩下的是谁
{
cout << a[i] << " ";//这步可以省略。打印出来.........纯属是我想确认下数组中是否只有一个1
if (a[i] == 1)
{
re_turn = i;
}
}
cout << endl;
delete [] a;//不要忘记delete掉在堆上new的空间
return re_turn + 1;//因为从1开始报数,所以+1
}
int main()
{
int num = 0;
cout << "input how many people ;";
cin >> num;
cout<<"the last is :"<<func(num)<<endl;
system("pause");
return 0;
}

#include
#define N 100
void main(void)
{
int i;
int n;
int m; //m为出局的人
int k;
int num[N];
int *p=num;
printf("请输入人数:
");
scanf("%d",&n);
for(i=0; i<n; i++) //给数组num[]赋值从1开始到n
{
*(p+i)=i+1;
}
k=0;
m=0;
i=0;
while(m<n-1) //当出局了12个人之后跳出循环
{
if(*(p+i)!=0)
{
k++;
}
if(k==3) //k表示点到第三个之后要出局
{
*(p+i)=0; //把第出局的人记0
m++;
k=0; //k置0,从新计算
}
i++;
if(i==n) //当i=13时,把i置为0,从新从第一个开始点
{
i=0;
}
}
while(*p==0) //唯一没有置0的就是剩到最后的
{
p++;
}
printf("最后留下的是第%d个人。
",*p);
}

7. 题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到5报数...
答:include<stdio.h> define MAX 500 main(){ int i,k,m,n,people[MAX],*p;printf("please input the number of people:");scanf("%d",&n);p=people;for(i=0;i<n;i++)(p+i)=i+1;i=0;k=0;m=0;while(m<n-1){ if(*(p+i)!=0)k++;if(k==5){ (p+i)=0;k=0;m++...

N个人围成一个圈顺序编号,从第一个人开始报数(从1到M),凡报到M的人退 ...
答:void Josegh(n){ int i,j,k,s1,w;s1=s;for(i=1;i<=n;i++) /*给n个人从1到n编号*/ p[i-1]=i;for(i=n;i>=2;i--){ s1=(s1+m-1)%i; /*下一个开始报数的人的编号是(s1+m-1)%i*/ if(s1==0) /*若s1为0,则说明要开始报数的是最后一个人*/ s1=i;w=p[s1-...

C++ 结构有n个人围成一圈,顺序排号。从第一个开始报数(从1到3报数...
答:int g_all_num = 0;//记录当前所有人数 int g_now=0;//人数计数 将g_now==3 的人的 struct Number { bool bOut;//是否已退出 int iSelf;//记录自己位置 Number* next;//指向下一个 };用上面结构体做个链表,添加所有人,做成圆形链表 //一次踢人判断如下 Number* tNumber = ***;...

C语言编程:n个人围坐一圈,顺序编号,从第1个人开始报数,从1报到5,凡...
答:i++) *(p+i)=i+1; i=0; k=0; m=0; while(m<n-1) { if(*(p+i)!=0) k++; if(k==5) { *(p+i)=0; k=0; m++; } i++; if(i==n) i=0; } while(*p==0) p++; printf("最后留下的是原来编号为%d的那个人\n",*p);} ...

n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的...
答:define N 5 void ysf(int *a,int n){ int *p=a,chu=0,callnum=0;while (chu<n-1){ if(*p!=0){ callnum++;if(callnum==3){ chu++;p=0;callnum=0;} } if(p==(a+n-1)){ p=a;continue;} p++;} for (p=a;p<a+n;p++){ if (*p!=0){ printf("最后剩余人的...

java编程,有n个人围成一圈,顺序排号,从一号到n号,从第一个开始报数...
答:person;for (int i = 1; i <= n; i++) {person = new Person(i);personQuan.addPerson(person);}n = 0;person = personQuan.first;while (personQuan.first != personQuan.last) {n++;if (n % 3 == 0) {//System.out.println("第" + n/3 + "次移除编号:" + person....

有n个人围成一圈,顺序从1开始顺序编号。从第一个人开始报数(从1报到3...
答:0, 1, 2, 3, ..., k-2, , k, ..., n-1 // 除去第k人,即除去序号为k-1的人 (2)k, k+1, ..., n-1, 0, 1, ..., k-2// 以序号k为起始,从k开始报0 (3)0, 1, ..., n-k-1, n-k, n-k+1, ..., n-2  // 作编号转换,...

vb有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3...
答:Do Until n = 1 For i = 1 To UBound(a)If a(i) = False Then k = k + 1 If k = 3 Then k = 0 a(i) = True n = n - 1 Print "编号为" & i & "者退出"End If End If Next i Loop For i = 1 To UBound(a)If a(i) = False Then Print "最终剩下编号为" ...

C语言指针 有n个人围城一圈,顺序排号。从第一个人开始报数(从1报到3...
答:此问题被称为约瑟夫问题,比较经典。下面为单链表处理上述问题并对问题进行了优化,即你可以输入每次报到几时有人退出圈子和刚开始从第几个人开始报数。include<stdio.h> include<malloc.h> typedef struct node { int data;struct node *next;}SeqList,*PSeqList;int main(){ int length,i=1,m,s...

有n人围成一圈,顺序排号,从1到3报数,凡报到3的人退出,问最后留下的是...
答:因为是到3循环一次,所以报道3那个人就退出,然后从下一个人也就是p+i了;把他的下标作为0,然后+1就好了