/*************************************************
Copyright (C), 1988-1999, Huawei Tech. Co., Ltd.
File name: // shu3.c
Author: Version: Date: // 回尚宁 第一版 2013-7-20
Description: //有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人
//退出圈子,问最后最后留下的是原来第几号的那位.
// 本函数并未引用其他函数
Others: // 其它内容的说明
Function List: // 主要函数列表,每条记录应包括函数名及功能简要说明
History: // 修改历史记录列表,每条修改记录应包括修改日期、修改
// 者及修改内容简述
1. Date:// 2013.7.20
Author://Mr.hui
Modification://
*************************************************/
/*************************************************
Function: // 逢三退一循环函数
Description: // 有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的 //人退出圈子,问最后最后留下的是原来第几号的那位
Calls: // while if
Called By: // 调用本函数的函数清单
Input: //num_input 变量
//count 局部变量
//num 局部变量
//jishu 局部变量
//a[]局部数组
Output: // 输出的是最后剩下人员的编号。
Return: // 函数返回值的说明
Others: // 其它说明
*************************************************/
#include<stdio.h>
main()
{
int num_input; //输入人数n
int a[1000]; //定义一个数组,n<=1000
int count; //用于给a[]赋值的局部变量
int num=1; //用以标志人员的序号
int jishu=0; //用以计数退出循环的人数
printf("please input a number");
scanf("%d",&num_input);
/*给数组赋值 */
for(count = 1;count <= num_input;count++)
{
a[count] = count;
}
/*开始循环,直到只剩下一个人为止*/
while(1)
{
/*遇到0则跳过,若数完一圈,则循环计数*/
while(!a[num]) //若下一人的编号对应的数组值为表示其已经退出的0,则跳过
{ // 继续计数,知道下一个数组值不为0为止
num++;
/*若数完一圈,则循环计数*/
if(num>num_input)
{
num = 1; //数完一圈时重新回到第一个人接着循环
}
}
num++; //对应的人员喊出的数字为1,跳过
/*若数完一圈,则循环计数*/
if(num > num_input)
{
num = 1;
}
/*遇到0则跳过,若数完一圈,则循环计数*/
while(!a[num])
{
num++;
if(num > num_input)
{
num = 1;
}
}
num++; //对应的人员喊出的数字为2,跳过
if(num > num_input)
{
num = 1;
}
/*遇到0则跳过,若数完一圈,则循环计数*/
while(!a[num])
{
num++;
if(num > num_input)
{
num = 1;
}
}
a[num] = 0; //对应的人员喊出的数字为3,退出循环,对应数组值置0
jishu++; //
/*遇到0则跳过,若数完一圈,则循环计数*/
while(!a[num])
{
num++;
if(num > num_input)
{
num = 1;
}
}
/* 若剩下的人数大于1,则返回至开头继续循环
若只剩下一个人,则停止循环*/
if(jishu == num_input-1) //退出的人数等于 总人数-1
break; //跳出循环
}
printf("%d",num); //输出剩下的一个人的编号
}