zoukankan      html  css  js  c++  java
  • 约瑟夫环

    问题概述

    编号为1至n的n个人围成一圈(之后编号为为i的人简称i)i在i+1左边,n在1的左边。

    从1开始报数,i报完数后在他右边的人继续报数,如果i所报的数为m的倍数那么这个人就出圈

    持续报数到只剩一个人

    按出圈顺序输出编号。

    方法1

    我们设sta[i]为0表示i已经出圈,为1表示还在圈内

    设pl为当前所处位置

    如果一个人出圈就把sta修改为0

    然后模拟报数过程并且跳过sta[i]=0的位置即可

    #include<cstdio>
    const int N=1e5+5;
    int sta[N];
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) sta[i]=1; 
        for(int i=1,pl=1;i<=n;++i)
            for(int j=m;j;){
                if(sta[pl]){
                    --j;
                    if(!j){
                        printf("%d ",pl);
                        sta[pl]=0;
                    }
                }
                pl++;
                if(pl>n) pl-=n; 
            }
        return 0;
    }

     方法2:

    与之前的方法相似,只是用链表连接

    删除时将其从链表中清除即可。

    #include<cstdio>
    const int N=1e5+5;
    int nex[N],pre[N];
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) nex[i]=i+1,pre[i]=i-1;
        nex[n]=1;pre[1]=n;
        for(int i=1,pl=1;i<=n;++i){
            for(int j=1;j<m;++j) pl=nex[pl];
            printf("%d ",pl);
            int t=nex[pl];
            pre[t]=pre[pl];
            nex[pre[t]]=t;
            pl=t; 
        } 
        return 0;
    }

    转载一个数学方法求输出序列中的最后一个:https://www.cnblogs.com/AllenDuane/p/3748203.html 

  • 相关阅读:
    回流和重绘
    php 异常捕获的坑
    每周散记 20180806
    转: Linux mount/unmount命令
    python http 请求 响应 post表单提交
    每周散记 20180723
    优惠劵产品分析
    c++ 软件版本比较函数
    每周散记
    转: 系统问题排查思路
  • 原文地址:https://www.cnblogs.com/bzmd/p/11105227.html
Copyright © 2011-2022 走看看