报数(约瑟夫环游戏)
题目描述:有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。
输入
初始人数n
输出
最后一人的初始编号
样例输入:
3
样例输出:
2
#include<stdio.h>
void find(int n)
{
int p[n];
for(int i=0;i<n;i++)
{
p[i]=1;
}
int count=0,index=0,sheng=n;
while(sheng>1)
{
if(p[index]==1)
{
count++;
if(count==3)
{
p[index]=0;
count=0;
sheng--;
}
}
index=(index+1)%n;
}
for(int i=0;i<n;i++)
{
if(p[i]==1)
{
printf("%d",i+1);
break;
}
}
}
int main(void)
{
int n;
scanf("%d",&n);
find(n);
return 0;
}
在自定义函数find中,定义数组p[n]用循环使每个元素为1,表示人在游戏中
0则表示人已经出局不在游戏里面
用index表示数组下标index+1等于第几号人
用count表示报号次数
while函数当只剩下一个人时跳出循环,首先判断人在不在游戏中
若在游戏中则count+1,表示报号了
当count=3也就是满3个人报号
那么第三个人出局,讲其下标变成0同时剩下的人数减一count清0
对 index = (index + 1) % n; 这行代码的详细解释:
在这段代码所实现的约瑟夫环逻辑中,我们使用数组 people 来模拟围成一圈的人,index 变量用于表示当前所指向的人的数组下标位置,目的是按顺序遍历这个 “圈” 里的每个人。
循环遍历需求: 因为这是模拟一个环形结构(就像人们真的围成一个圈一样),当遍历到数组末尾(也就是最后一个元素,下标为 n - 1,假设数组大小为 n)后,下一次应该回到数组开头(下标为 0)继续遍历,以此来实现循环报数等操作,不断重复这个过程,直到剩下最后一个人为止。
取余运算(%)在这里起到关键作用。
例如,假设 n 的值为 5(即有 5 个人,数组 people 大小为 5,下标范围是 0 到 4),当 index 当前值为 4 时(已经指向数组最后一个元素了),执行 index = (index + 1) % n 操作: 先计算 index + 1,此时 index + 1 的值为 5。 然后进行取余运算 5 % 5,结果为 0,所以 index 就被更新为 0,正好回到了数组的开头位置,实现了模拟环形结构下的 “循环向后移动” 的效果。
再比如,如果 index 当前值是 3,执行 index = (index + 1) % n (n 还是 5): 先计算 index + 1,得到 4。 接着 4 % 5 的结果就是 4,那么 index 的值更新为 4,也就是按照顺序正常往后移动了一位指向了下一个元素(符合在圈里按顺序往后走到下一个人的逻辑)。
所以,index = (index + 1) % n; 这行代码通过利用取余运算的特性,巧妙地让表示当前位置的 index 变量能够在数组模拟的环形结构中不断循环移动,从而可以正确地按顺序遍历每一个人,进而实现整个约瑟夫环报数、出圈等流程的模拟。
原文地址:https://blog.csdn.net/2401_88221221/article/details/144373744
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!