请问这道约瑟夫问题的代码如何理解呢?

请问这道约瑟夫问题的代码如何理解呢?希望帮逐行注释一下代码,并说一下思路。
问题描述:
有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王。编程输入n和m,输出最后猴王的编号。

img

#include<cstdlib>
#include<cstdio>

int flag[305];

void int()
{
    for (int index = 0; index < 305; index++)
    {
        flag[index] = 0;
    }
}

int main()
{
    int n, m;
    scanf("%d", &n);
    scanf("%d", &m);
    while (n != 0 && m != 0)
    {
        int index = -1;
        int count = 0;
        init(); //全都没有数过
        for (int i = 1; i < n; i++)
        {
            count = 0;
            while (count != m)
            {
                index = (index + 1) % n;   //到圈尾,取模
                if (flag[index] == 0)
                {
                    //如果还没有退出圈,累加数量
                    //如果累加到m,该位置的点退出圈,置1
                    count++;
                    if (count == m)
                    {
                        flag[index] = 1;
                    }
                }
            }
        }
    //打印出最后未出圈的点
    for (int j = 0; j < n; j++)
    {
        if (flag[j] == 0)
        {
            printf("%d\n", j + 1);
            break;
        }
    }
    scanf("%d", &n);
    scanf("%d", &m);
   }
   return 0;
}

#include<cstdlib>
#include<cstdio>
int flag[305];
void int()
{
    for (int index = 0; index < 305; index++)
    {
        flag[index] = 0;
    }
}
int main()
{
    int n, m;
    scanf("%d", &n);
    scanf("%d", &m);
    while (n != 0 && m != 0)    //都为0则退出循环
    {
        int index = -1;
        int count = 0;
        init(); //全都没有数过,都设置为0
        for (int i = 1; i < n; i++)    //最多需要循环 n-1次,每次淘汰一只猴子
        {
            count = 0;//每次循环将count设置为0
            while (count != m) //当还没有数到m时进行循环数
            {
                index = (index + 1) % n;   //到圈尾,取模
                if (flag[index] == 0) //找到没有被淘汰的猴子时,增加计数。如果计数到达m,则淘汰这只猴子
                {
                    //如果还没有退出圈,累加数量
                    //如果累加到m,该位置的点退出圈,置1
                    count++;
                    if (count == m)
                    {
                        flag[index] = 1;  //淘汰这只倒霉的猴子 
                    }
                }
            }
        }
    //打印出最后未出圈的点
    for (int j = 0; j < n; j++)
    {
        if (flag[j] == 0)    //最后只有一个猴子的标志还是0,所以找到后输出这只猴子编号,然后break跳出循环就好了
        {
            printf("%d\n", j + 1);
            break;
        }
    }
    scanf("%d", &n);   //继续玩下一个游戏,直到输入都是0
    scanf("%d", &m);
   }
   return 0;
}
 


#include<cstdlib>
#include<cstdio>
int flag[305];
void int()
{
    for (int index = 0; index < 305; index++)
    {
        flag[index] = 0;
    }
}
int main()
{
    int n, m;
    scanf("%d", &n);
    scanf("%d", &m);
    while (n != 0 && m != 0)    //都为0则退出循环
    {
        int index = -1;//跑位置
        int count = 0;//计没被淘汰的猴子的数
        init(); //全都没有数过,都设置为0
        for (int i = 1; i < n; i++)    //最多需要循环 n-1次,每次淘汰一只猴子
        {
            count = 0;//每次循环将count设置为0
            while (count != m) //当还没有数到m时进行循环数
            {
                index = (index + 1) % n;   //到圈尾,取模
                if (flag[index] == 0) //找到没有被淘汰的猴子时,增加计数。如果计数到达m,则淘汰这只猴子
                {
                    //如果还没有退出圈,累加数量
                    //如果累加到m,该位置的点退出圈,置1
                    count++;
                    if (count == m)
                    {
                        flag[index] = 1;  //这只猴子出圈 
                    }
                }
            }
        }
    //打印出最后未出圈的点
    for (int j = 0; j < n; j++)
    {
        if (flag[j] == 0)    //最后只有一个猴子的标志还是0,所以找到后输出这只猴子编号,然后break跳出循环就好了
        {
            printf("%d\n", j + 1);
            break;
        }
    }
    scanf("%d", &n);   //继续玩下一个游戏,直到输入都是0
    scanf("%d", &m);
   }
   return 0;
}