约瑟夫问题:N个人围成一圈,从第一个人开始报数,数到M的人出圈;再由下一个人从1开始报数,数到M的人出圈;……直到只剩1人,输出依次出圈的人的编号。
N,M由键盘输入,0 <M <= N <20。
函数第一个参数设计为指针,传主函数的数组作为参数。输出时,每个数字后有且仅有一个空格。
例如N=7,M=2,表示7个人围坐一圈,从1号开始报数,数到2的就出列。第一轮转圈中,2、4、6号依次出列。还剩下7、1、3、5四个数字。第二圈又是数到2的数列,1和5出列。第三圈的时候,只剩下3和7列。最终的输出结果是: 2 4 6 1 5 3 7
函数接口定义:
void yuesefu(int *p,int n,int m);
指针 p
指向一个一维数组,数组的元素数量是n
个。 m
表示传入的报数的数字。
裁判测试程序样例:
#include<stdio.h>
#define L 20
//指针p指向的一维数组有n个元素,然后按照数字m进行报数出列。
void yuesefu(int *p,int n,int m);
int main()
{
int a[L];
int M,N;
scanf("%d%d",&N,&M);
yuesefu(a,N,M);
}
/* 请在这里填写答案 */
输入样例:
有7个人,从第一个人开始报数,数到2的出列。
7 2
结尾无空行
输出样例:
出列的顺序,注意每个数字后,有且仅有一个空格。
2 4 6 1 5 3 7
首先我们来分析这道题,n个人围成一圈,轮流报数,每次报到m的人出列,这样到最后,所有人都会出列。对于这道题呢,需要我们用再定义一个数组进行记录出列情况,,先对他初始化为0,再进入循环
void yuesefu(int *p,int n,int m)
{
int k = 0,u = 0;//利用u来记录出列的数的个数,判断是否结束循环,k来记录报数情况
int i;
int b[25] = {0};//b[]记录是否已经出列
for(i = 0;i < n;i++)
{
p[i] = i + 1;//对数组进行初始化,填数
}
while(u < n)//判断结束条件
{
for(i = 0;i < n;i++)
{
if(b[i] == 0)//只有未出列的数才可以出列
{
k++;
if(k == m)//当报数为m时出列
{
printf("%d ",p[i]);//打印
b[i] ++ ;//标记已经出列的数
k = 0 ;//重新进行报数
u++;//记录出列的数的个数,用于结束循环
}
}
}
}
}
如果出列那我们 让他加1,每次我们判断只有报到m并且记录数组为0的数打印出来,当打印n个时,结束循环即可。