题目:有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子, 问最后留下的是原来第几号的那位?
#include <stdio.h>
#define N 5
//有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数), 凡报到3的人退出圈子,问最后留下的是原来第几号的那位。(*)
void main()
{
int i,j,k,a[N+1],*p; //a = 0 1 2 3 4 5
//编号
for (i =0, p=a; p <= a + N; i++, p++)
*p = i;
p = a + 1; // *p = 1
k = N;
for (i = 0,j = 1; k!=1;j++) {
if (p > (a + N))
p = a+1;
if (*p !=0)
i++;
if ((i-3) == 0) {
printf("k=%d out %d\n", k, *p);
*p= 0;i=0;k--;
}
p++;
}
//打印最终结果
for (i=1;i<=N; i++)
if (a[i] !=0)
printf("the last number is %d\n", a[i]);
}
方法二:
//方法二:
#include<stdio.h>
#define N 50
void main()
{
int peopleNum[N];
int totalNum = 0;//总人数
int restNum = 0;//剩余人数
int count = 0;//报的数
scanf("%d", &totalNum);
for (int i = 0; i < totalNum; i++)
{
peopleNum[i] = i + 1;//赋予每个人编号
}
restNum = totalNum;//一开始全部人都在
while (restNum>1)//只要不是剩下一个人
{
int* curNum = peopleNum;//每次报完一轮数,再报第二轮要重头开始
while (curNum < peopleNum + totalNum)//没有报完一轮,就继续报数,让人滚蛋
{
if (*curNum!=0)//设0为被剔除人的标识
{
count++;
if (count==3)//报到3的人滚蛋
{
*curNum = 0;//标识滚蛋的人
count = 1;//从1开始重新1,2,3报数
restNum--;//让一个人滚了,所以剩余的人数少一个
}
}
curNum++;
}
}
for (int i = 0; i < totalNum; i++)
{
if (peopleNum[i]!=0)//只要不是滚出去的人,也就是留在场上的人,其实只会有一个
{
printf("The last one is %d", peopleNum[i]);
break;
}
}
}
执行结果: