已知有N个人围成一圈,假设从第S个人从1开始报数,当有人报数为M或M的倍数,该人出圈,请用C语言编程,把这N个人的顺序求出来。
假设N=100
S=1
M=10
參考答案:#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(\ out.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);
}
--------------------------------------------------------------------------------
/* 注:题中第一个for()循环是先对数组p赋初值。在第二个for()中用i来控制没出圈的
总人数,s1=(s1+m-1)%i的作用是找出报数后出圈人的下标,其中对i求余的作用是使报
数按圈进行(即报到尾后又从头报),该算法在很多题目中都用到。由于求余的作用当
报数正好到最后一个时s1为0,故而要进行if(s1==0)的判断。内嵌的for()循环是将出圈
以后的人依次往前移。*/
void Josegh(void)
{
int i,j,s1,w;
s1=s;
for(i=1;i<=n;i++)
p[i-1]=i;
for(i=n;i>=2;i--)
{s1=(s1+m-1)%i;
if(s1==0)
s1=i;
w=p[s1-1];
for(j=s1;j<i;j++)
p[j-1]=p[j];
p[i-1]=w;
}
}
void Josegh(void)
{
int i,j,k,s1,w;
for(i=0;i<n;i++) p[i]=i+1;
j=n;
s1=s-1;
while(j!=1)
{
s1=(s1+m-1)%j;
w=p[s1];
for(k=s1;k<j-1;k++)
p[k]=p[k+1];
p[k]=w;
j--;
}
}
参考资料:南开一百题