有n个人围城一个圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号那位。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define nmax 50
int main()
{
//i是循环变量,代表着循环到第i+1个人
//n是总人数
//num是这些人围成的圈,其中,num[n]到num[49]无意义
//k是循环到的那个人报的数
//m是已经退出了几个人
int i,k,m,n,num[nmax],*p;
printf("请输入总人数:");
scanf("%d",&n);
p=num;
for(i=0;i<n;i++){
*(p+i)=i+1; //对数组中的各元素进行 1到n的赋值 ,也就是每个人的标号
}
i=0;
k=0;
m=0;
//依次报数1,2,3,报到3的元素使之值为0,重复n-1次
while(m<n-1){ //当退出去的人等于n-1时(即只剩一人),循环退出
//因为有n个人,m为退出的人数,当while循环m不小于n-1时,表达式为0,退出循环,即只剩一人
if(*(p+i)!=0)k++; //如果这个人没有退出圈子,就报数
//每个人报数,从1开始,k相当于每个人报的数字
if(k==3){
*(p+i)=0; //因为这个人报到3,把他的值设为0,表示他已退出该圈
k=0; //再将k置为0.重新开始报数
m++; } //退出的人数加1}
i++; //表示指针的移动,一个一个报数
if(i==n) //当i==n时,表示报到了最后一个
i=0; //将i置0,再从第一个开始报
}
while(*p==0)
p++; //上面那个循环结束后,只有一个人留了下来,然后指针开始寻找最后剩下的一个人
//上面这句话执行完之后,p指向剩下来那一个。
printf("%d \n",*p);
return 0;
}
//整个程序n个人围城的圈不发生改变,只有每次报到的那个人,它本身的标志变为0,于是在第一个循环中,if(!=0)那个语句
//可以在接下来的报数中不将等于0的人计算在内