zoukankan      html  css  js  c++  java
  • 1282 约瑟夫问题

    1282 约瑟夫问题

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 大师 Master
     
     
     
    题目描述 Description

    有编号从1到N的N个小朋友在玩一种出圈的游戏。开始时N个小朋友围成一圈,编号为I+1的小朋友站在编号为I小朋友左边。编号为1的小朋友站在编号为N的小朋友左边。首先编号为1的小朋友开始报数,接着站在左边的小朋友顺序报数,直到数到某个数字M时就出圈。直到只剩下1个小朋友,则游戏完毕。

    现在给定N,M,求N个小朋友的出圈顺序。

    输入描述 Input Description

    唯一的一行包含两个整数N,M。(1<=N,M<=30000)

    输出描述 Output Description

    唯一的一行包含N个整数,每两个整数中间用空格隔开,第I个整数表示第I个出圈的小朋友的编号。

    样例输入 Sample Input

    5 3

    样例输出 Sample Output

    3 1 5 2 4

    数据范围及提示 Data Size & Hint
     

    分类标签 Tags 点此展开 

     
     
    题解:模拟线段树的单点修改,注意代码中的tmp的变化
    #include<bits/stdc++.h>
    using namespace std;
    #define N 30005
    #define lc k<<1
    #define rc k<<1|1
    int n,k,a[N<<2];
    void build(int k,int l,int r){
        if(l==r){
            a[k]=1;return ;
        }
        int mid=l+r>>1;
        build(lc,l,mid);
        build(rc,mid+1,r);
        a[k]=a[lc]+a[rc];
    }
    int query(int k,int l,int r,int pos){
        if(l==r){
            a[k]=0;return l;
        }
        int mid=l+r>>1,ans;
        if(a[lc]>=pos)
            ans=query(lc,l,mid,pos);
        else
            ans=query(rc,mid+1,r,pos-a[lc]);
        a[k]=a[lc]+a[rc];
        return ans;
    }
    int main(){
        scanf("%d%d",&n,&k);
        build(1,1,n);
        for(int i=1,tmp=k;i<=n;i++){
            printf("%d ",query(1,1,n,tmp));
            if(i!=n) tmp=(tmp+k-1)%(n-i);
            if(!tmp) tmp=n-i;
        }
        return 0;
    }
  • 相关阅读:
    天兔监控系统安装
    day6
    day5
    day4
    day3
    day2
    day1
    几个重要的Xenomai相关链接
    树莓派GPIO中断驱动程序
    转了一圈,再读LKD
  • 原文地址:https://www.cnblogs.com/shenben/p/5644003.html
Copyright © 2011-2022 走看看