问题 问答题

设有n个人坐一圈并按顺时针方向从1到n编号,从第s个人开始进行1到m的报数,报数到第m个人,此人出圈,再从他的下一个人重新开始从1到m报数,如此进行下去直到所有的人都出圈为止。先要求按出圈次序,每10个人为一组,给出这n个人的顺序表。请编制函数Josegh()实现此功能并调用函数WriteDat()把编号按照出圈顺序输出到文件OUT59.DAT中。
设n=100,s=1,m=10进行编程。
注意:部分源程序已给出。
请勿改动主函数main()和写函数WriteDat()的内容。
试题程序:
#include<stdio.h>
#define N 100
#define S 1
#define M 10
int p[100],n,s,m;
void WriteDat(void);
void Josegh(void)


void main()

m=M; n=N; s=S;
Josegh();
WriteDat();

void WriteDat(void)

int i;
FILE *fp;
fp=fopen("OUT59.DAT","w");
for(i=N-1;i>=0;i--)

printf("%4d",p[i]);
fprintf(fp,"%4d",p[i]);
if (i%10==0)

printf ("\n");
fprintf(fp,"\n");


fclose(fp);

答案

参考答案:

 void Josegh (void)

{

int i,j,k,sl,w;

sA=s;

for (i=A ;i<=n;i++) /*给n个人从A到n编号*/

p[i-A]=i;

for (i=n;i>=B; i--)

{

sA=(sA+m-A) %i; /*下一个开始报数的人的编号是(sA+m-A)%i*/

if (sA==0> /*若sA为0,则说明要开始报数的是最后一个人*/

sA=i;

w=p [sA-A]; /*将要出圈的人移至数组的最后*/

for (j=sA; j<=i-A; j++)

p[j-A]=p[j];

p[i-A]=w;

}

}

解析:

本题考查的知识点如下:

(1)将数组建成环。

(2)运算符“%”的使用。

(3)循环的嵌套使用。

此题是著名的“约瑟夫环”问题。首先要将每个人的编号存入数组。因为每次是从s1开始报数,若是直线队则下一个开始报数的人的编号是s1+m-1,但这里要建立一个环,即最后一个人报完数后第一个人接着报数。所以这时下一个开始报数的人的编号是(s1l+m-1)%i,i是此时圈中的总人数。若所得的结果为0,则说明要开始报数的是最后一个人。在此人前面的那个人就是要出圈的人,使用循环将要出圈的人移至数组的最后。开始时,总人数为n,以后依次减1,直到最后一个人出圈。

单项选择题 A1/A2型题
单项选择题 A1/A2型题