UVA 133 The Dole Queue 约瑟夫问题的变种,手写链表,模拟

本文介绍了一种解决约瑟夫问题及其变种的手动模拟方法,通过使用链表结构来提高效率。作者详细解释了如何维护链表中元素的左右指针,并在删除元素时更新这些指针。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

连约瑟夫问题的公式都不会,更何况变种了,只好手动模拟

好吧,我确实想到了删除一个数就把它置为0,然后要走的时候再判断...

可是我觉得一旦n变大了,这种方法需要的时间也随之上升,因此手写一个链表来走好了

le[i]代表第i个元素左边的元素的下标,ri[i]代表第i个元素右边元素的下标 ,sz表示链表里还有多少元素。

不过因为我的实现的缘故,依然要把删除的元素置为0,不过我觉得还是比原来的方法要快

删除的时候只要修改左边元素的ri和右边元素的le就好了,以下是代码

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

int n,k,m,arr[25],be,ed,le[25],ri[25],sz;

int main(){
    while(scanf("%d%d%d",&n,&k,&m)==3&&n){
        sz=n;
        for(int i=0;i<n;++i)
            arr[i]=n-i,le[i]=(i-1+n)%n,ri[i]=(i+1)%n;
        be=n-1,ed=0;
        while(sz){
            for(int i=1;i<k;++i)
                be=le[be];
            for(int i=1;i<m;++i)
                ed=ri[ed];
            if(sz==1&&be==ed){
                printf(" %2d\n",arr[be]);
                break;
            }
            else if(sz==2&&be!=ed){
                printf(" %2d %2d\n",arr[be],arr[ed]);
                break;
            }
            else if(be==ed){
                printf(" %2d,",arr[be]);
                --sz;
                arr[be]=0;
                ri[le[be]]=ri[be];
                le[ri[be]]=le[be];
                while(!arr[be])
                    be=le[be];
                while(!arr[ed])
                    ed=ri[ed];
            }
            else{
                printf(" %2d %2d,",arr[be],arr[ed]);
                arr[be]=arr[ed]=0;
                sz-=2;
                ri[le[be]]=ri[be];
                le[ri[be]]=le[be];
                ri[le[ed]]=ri[ed];
                le[ri[ed]]=le[ed];
                while(!arr[be])
                    be=le[be];
                while(!arr[ed])
                    ed=ri[ed];
            }
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值