设有n个人坐一圈并按顺时针方向从1到n编号,从第s个人开始进行1到m的报数,报数到第m个人,此人出圈,再从他的下一个人重新开始从1到m报数,如此进行下去直到所有的人都出圈为止。先要求按出圈次序,每10个人为一组,给出这n个人的顺序表。请编制函数Josegh

admin2009-02-19  32

问题 设有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 );
           fprintf(fp, "%4d",p);
           if (i%10==0)
           {
               printf("\n");
               fprintf(fp,"\n");
           }
       }
       fclose(fp);
   }

选项

答案void Josegh(void) { 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-1]; /*将要出圈的人移至数组的最后*/ for(j=s1;j<=i-1;j++) p[j-1]=p[j]; p[i-1]=w; } }

解析 本题考查的知识点如下:
(1)将数组建成环。
(2)运算符“%”的使用。
(3)循环的嵌套使用。
此题是著名的“约瑟夫环”问题。首先要将每个人的编号存入数组。因为每次是从s1开始报数,若是直线队则下一个开始报数的人的编号是s1+m-1,但这里要建立一个环,即最后一个人报完数后第一个人接着报数。所以这时下一个开始报数的人的编号是(s1+m-1)%i,i是此时圈中的总人数。若所得的结果为0,则说明要开始报数的是最后一个人。在此人前面的那个人就是要出圈的人,使用循环将要出圈的人移至数组的最后。开始时,总人数为n,以后依次减1,直到最后一个人出圈。
转载请注明原文地址:https://jikaoti.com/ti/l7Q7FFFM
0

相关试题推荐
最新回复(0)