【绕圈报数】
1130 更新 ======== 一般化情况
13个人围成一圈,从第1个人开始顺序报号1、2、3,凡报到3的人退出圈子。找出最后留在圈子里的人原来的序号。
输出提示 “出圈成员及顺序:” 格式 “%3d”
输出提示 “\n最后的成员是:” 格式 “%3d”
Talk is cheap, show me the code.
#include <stdio.h>
int main()
{
int person[13] = {
0}; //0表示没有出圈,1表示出圈
int number=0; //每个人报的数(1、2、3、1、2、3...这样报数)
int counter=0; //统计出圈人数
int i=0;
printf("出圈成员及顺序:");
do{
if(person[i%13] == 0) //取余是重点!对于圈型,用i%13计数,一圈到头就下一圈,不超过13
number++; //没有出圈,就要报数
if(number == 3){
//报数到3
person[i%13] = 1; //出圈
printf("%3d", i%13+1);
counter++; //出圈人数++
number = 0; //number复位,重新计数
}
i++;
}while(counter<12); //出圈人数足够!
printf("\n最后的成员是:"); //输出圈内的人
for(i=0;i<13;i++)
{
if(person[i]==0) printf("%3d", i+1);
}
return 0;
}
一般化
n个人围成一圈,顺序编号。从第一个人开始从1到m报数,凡报到m的人退出圈子,编程求解最后留下的人的初始编号。
/*
n个人围成一圈,顺序编号。从第一个人开始从1到m报数,
凡报到m的人退出圈子,编程求解最后留下的人的初始编号。
样例输入:(第一行输入)
6 3(两个输入数据之间有空格)
样例输出:(换行输出)
1
*/
#include<stdio.h>
#include<stdlib.h>
#define max 100
int loop[max+10];
int main()
{
int n, m, i; //n表示总人数,报到m出圈
scanf("%d%d",&n,&m);
for(i=0;i<n;i++) loop[i]=i; //初始化{1, 2..., n},使编号对应
int dest=0; //用dest遍历每个人
for(i=0;i<n;i++) //循环一次,出圈一人
{
int count=0; //count表示当前报的数
while(count<m) //还没报到m
{
while(loop[dest]==0) dest=(dest+1)%n;
//如果dest不在圈子中,那么执行dest+1下一个人, %n保证在圈内循环
count++; //while循环退出,表示此人在圈中,报数
dest=(dest+1)%n; //下一个人
}
dest--; //退出循环时虽然count=m, 但多执行了一步“下一个人”, 退回上一个即为报m的人
if(dest<0) dest=n-1;
//特殊情况:圈末(dest=n-1)报了m,
//while循环中“下一个人”后,到了圈首(dest=0),
//--后(dest<0)
if(i==n-1) printf("%d\n",loop[dest]);//在最后一个人出圈之前输出
loop[dest]=0; //置0表示出圈,进入for下一个循环
}
return 0;
}
类似题型还有:
鲁智深吃馒头 和 约瑟夫问题
思路相仿,可以借鉴。
(看见有人用了结构体,待补充…)
注:源代码是我解决约瑟夫问题时借鉴的别人的CSDN的文章
现在一时找不到原文章了 = = 发了原创
此文章记录自己的做题心得以及分享给需要的朋友
不从此获利,侵删。