约瑟夫环(简单理解版)

特别强调:这一篇适合与刚刚学数据结构的uu们,因为我就是才开始学就遇上了老师布置的这道题 所以写下了这篇blog记录一下 希望你们也能看懂哦~

约瑟夫环问题:任给正整数N和K,按下述方法可以得到1,2, …,N的一个置换,将数字1,2,…,n环形排列,按顺时针方向自1开始报数,报到K时输出该位置上的数字,并使其出列。然后从他在顺时针方向的下一个数字继续报数,如此下去,直到所有的数字全部出列为止。例如N=10,K=3,则正确的出列顺序应为3,6,9,2,7,1,8,5,10,4。

分析过程:

把约瑟夫环看作一个圈圈⭕️ 首尾相连 为了遍历所有的数字 则利用while循环。

用数组给每个数字标记为0,如果一个数字列出则标为1 一个一个出圈 直到所有的数字由标记0到1为止。number用来计数出圈的人数 当number与N个数相等的时候 while循环结束~

因为数到K的那个数字就要出圈,所以需要index计算1~K的下标。当index == K时,数字就出圈了,顺便标记为1,即arr[c] = 1。

大体过程就是这样了....

注意⚠️的是 这个特殊情况 在最后的数字仅剩下4的时候时 循环内的c已经超过了N,所以要设置条件if(c > N) c = 1;使arr[c]从新开始查找标记为0的数字,直到条件满足的时候标记为1,出圈。

如果还是不太清楚的话 可以尝试自己画画哦~(大概就这样子)

int arr[11] = {0};//标记大家都是0
void test()
{
    int N,K; //N为从1开始到n K为K个K个的数
    cout<<"input N:";
    cin>>N;
    cout<<"input K:";
    cin>>K;
    int c=0;
    int number = 0;//number为出圈的人数
    int index = 0;//index为报数人的标号 从1~K
    while(number!=N)
    {
        c++; //c为当前人数的编号 也就是输出从1~n
        if(c>N){c=1;} //特殊情况
        if(arr[c] == 0)//大家都还没有出圈的时候 标记为0
        {
            index++;
            //k表示当前这个编号为c的人报数为k
            if(index == K)
            {
                arr[c] = 1;
                //标记为1 此数出圈
                number++;
                cout<<c<<"  ";
                index=0;
                //重制标号
            }
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值