题目1:
#include<stdio.h>
int main(void)
{
int N;
scanf("%d",&N);
int a[1100];
for(int i=1;i<=N;i++)
{
a[i]=i;//先初始化所有的人为未删除的状态 1
}
int con;
int k=0;//k是报数器
int n=0;//用n来记录删除的人数
for(int i=1;n<N;i++)
{
if(a[i]!=0)
{
k++;//只有没有被删除的人才可以报数
if(k==3)//如果报数到了3
{
a[i]=0;//删除该位置上的人
n++;//删除的人数加一
if(n==N)//如果所有的人都被删除了 就输出最后一个删除的人的序号
printf("%d\n",i);
k=0;
}
}
if(i==N)//将直线队列的首尾相接 成一个环
i=0;
}
}
题目2
void CountOff( int n, int m, int out[] )//主要的报数函数
{
int a[1000];//原本为a[n]但是c是静态语言 不可以动态申请数组
int z=0; //i是总的计数器,h是退出个数的计数器,z是报数的计数器
//其中z要被设为0,这样在z为3的时候才报了三个数,退出
for(int i=0;i<n;i++)
{
a[i]=i+1;//不是以单纯的数字序列进行循环,用数组可以清楚的表示出那个已经退出
}//初始化状态为 未删除的 1 状态
for(int h=0,i = 0;h<n;)
{
if(a[i]!=0)
{
z++;//只有未退出的元素才可以报数
}
if(z==m)
{
h++;//删除的人数加一
out[i]=h;
z=0;//报数计数器归0
a[i]=0;//同时删去该元素,因为整个数组中都没有0,则可以用0来表示已经被删除
}
i++;// 向下一个元素遍历
if(i==n)
{
i=0;//防止i溢出,并再次从头开始 成环操作
}
}
return 0;
}