求大神编一段C程序,猴子当大王.链表方法我已经写出来了,但是用数组方法没能解决.所以要求要用数组做出来.有n只猴子,按顺时针方向围成一圈选大王(编号从1~n),从第1号开始报数,一直数

来源:学生作业帮助网 编辑:作业帮 时间:2024/05/09 05:54:57

求大神编一段C程序,猴子当大王.链表方法我已经写出来了,但是用数组方法没能解决.所以要求要用数组做出来.有n只猴子,按顺时针方向围成一圈选大王(编号从1~n),从第1号开始报数,一直数
求大神编一段C程序,猴子当大王.
链表方法我已经写出来了,但是用数组方法没能解决.
所以要求要用数组做出来.
有n只猴子,按顺时针方向围成一圈选大王(编号从1~n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数.就这样,直到圈内只剩下一只猴子时,这只猴子就是猴王,编程完成如下功能:输入n,m,输出最后猴王的编号.
Input
每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m, n < 300)
Output
对于每行输入数据,输出数据也是一行,即最后猴王的编号
测试数据
6 2 7 3 2 1 1 7 99 56
输出结果
5 4 2 7 16
Hint
约瑟夫环问题

求大神编一段C程序,猴子当大王.链表方法我已经写出来了,但是用数组方法没能解决.所以要求要用数组做出来.有n只猴子,按顺时针方向围成一圈选大王(编号从1~n),从第1号开始报数,一直数
用链表写的话比较好,资源占用少;用数组的话也行,如下:
这是一种关于约瑟夫循环的问题,所以一般用的循环单链表数据结构,具体细节参照我百度空间的一篇文章
#include "stdio.h"
#include <stdlib.h>
void main(void)
{
\x05int result(int *p,int n,int limit);
\x05int n=0;//总人数
\x05int m=0;//报数截止号
\x05int *p;
\x05for(;;)
\x05{
\x05\x05printf("input number of n and m :");
\x05\x05scanf("%d%d",&n,&m);
\x05\x05if (m<=0 || n<=0)
\x05\x05{
\x05\x05\x05exit(0);
\x05\x05}
\x05\x05p=(int *)malloc(n*sizeof(int));
\x05\x05printf("The king is NO.%d\n",result(p,n,m));
\x05\x05delete [] p;
\x05}
}
int result(int *p,int n,int limit)
{
\x05int i=0;
\x05for(i=0;i<n;i++)
\x05\x05p[i]=i+1;
\x05i=0;                   // i为每次循环时计数变量 
\x05int k=0;                   // k为按1,2,3...limit报数时的计数变量 
\x05int m=0;                   // m为退出人数 
\x05while (m<n-1)          // 当退出人数比n-1少时(即未退出人数大于1时)执行循环体
\x05{
\x05\x05if (p[i]!=0)  k++; //如果编号为0,就不报数;如果编号不为0,报数加1
\x05\x05if (k==limit)             // 将退出的人的编号置为0 
\x05\x05{
\x05\x05\x05p[i]=0;
\x05\x05\x05k=0;//重新开始报数
\x05\x05\x05m++;//退出人数加1
\x05\x05}
\x05\x05i++;
\x05\x05if (i==n) i=0;        // 报数到尾后,i恢复为0 
\x05}
\x05i=0;
\x05while(p[i]==0) i++;
\x05return p[i];
}
测试结果: