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 

  • 相关阅读:
    安装go版本
    golang简介
    安装MySQL
    art.dialog.art 中,将子页面窗口中的值传递给父框架中
    Windows7下安装CentOS
    生成uuid
    如何开启win7端口的图文教程
    PHPMailer不能发送邮件
    sql 如果关联表 没有值 设置 默认值
    php array 分页
  • 原文地址:https://www.cnblogs.com/bzmd/p/11105227.html
Copyright © 2011-2022 走看看