概述
问题描述
有n个人围成一圈,顺序排号(编号为1到n)。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子。从下一个人开始继续报数,直到剩下最后一个人,游戏结束。
问最后留下的是原来第几号的那位。
举个例子,8个人围成一圈:
1 2 3 4 5 6 7 8
第1次报数之后,3退出,剩下:
1 2 4 5 6 7 8 (现在从4开始报数)
第2次报数之后,6退出,剩下:
1 2 4 5 7 8 (现在从7开始报数)
第3次报数之后,1退出,剩下:
2 4 5 7 8 (现在从2开始报数)
第4次报数之后,5退出,剩下:
2 4 7 8 (现在从7开始报数)
第5次报数之后,2退出,剩下:
4 7 8 (现在从4开始报数)
第6次报数之后,8退出,剩下:
4 7 (现在从4开始报数)
最后一次报数之后,4退出,剩下:
7.
所以,最后留下来的人编号是7。
输入格式
一个正整数n,(1<n<10000)
输出格式
一个正整数,最后留下来的那个人的编号。
例子
样例输入
8
样例输出
7
跟前几天写那个狡猾的老鼠那道题99%一样,代码放上了,就是巧妙的模拟就是了。
#include <stdio.h>
#define m 3
int main ()
{
int n,n1,step,i;
scanf("%d",&n);
int a[n];
for(i=0;i<n;i++)
a[i]=0;
n1=n;
i=0;
while(n1>1)
{
step=m;
while(1)
{
i++;
if(i==n)
i=0;
if(a[i]==0)
step--;
if(step==0)
break;
}
a[i]=1;
n1--;
}
for(i=0;i<n;i++)
{
if(a[i]==0)
printf("%dn",i);
}
return 0;
}
在其他博主那看到另一种表达,也很不错呢:
他的思路:定义一维数组, 数组下标表示人的编号, 值表示是否出局(1为出局), 先将数组元素全部初始化为0, 然后定义两个整型变量 num 表示人的编号和 count 其所报的数(i 在0~2循环, 0即表示报数为3,则出局),再定义一个整型变量left记录剩余人数, 剩余1人时退出循环。此人为胜者并输出其编号。
#include <stdio.h>
int main(){
int a[10000] = {0};
int sum; //总人数
int num, count, left;
scanf("%d", &sum);
left = sum;
for(num=0,count=1; ; num=(num+1)%sum){
if(a[num] == 1) //若此人出局则继续找下一位未出局的人
continue;
if(count==0){ //若此人报数为 0 则此人出局
a[num] = 1;
left--;
if(left == 1)
break;
}
count=(count+1)%3;
}
for(num=0; num < sum; num++) //在数组中找到唯一未出局的人
if(a[num]==0)break;
printf("%d", num+1);
return 0;
}
最后
以上就是乐观爆米花为你收集整理的算法训练 - 筛选号码 (有n个人围成一圈,顺序排号(编号为1到n)。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子。从下一个人开始继续报数,直到剩下最后一个人,游戏结束。)的全部内容,希望文章能够帮你解决算法训练 - 筛选号码 (有n个人围成一圈,顺序排号(编号为1到n)。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子。从下一个人开始继续报数,直到剩下最后一个人,游戏结束。)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复