Uva133 The Dole Queue

约瑟夫问题的变种。

约瑟夫问题对我而言,有着特别的意义。我高一遇到的第一道难题就是约瑟夫问题;大一喜欢的女生问我的第一道问题也是约瑟夫问题(目前仍然为情所困,不知前途何方);链表的第一个实现也是约瑟夫问题。

这道题,就是有两个取孩子的操作。当然可以用链表做,但是lrj用的是数组模拟的方法,把取过的元素设置为0.这个方法很好,所以我也写了一个。


然后出现了这么几个bug:

1.题目意思一开始没看清楚,以为每次都是从1和n取,写错了一发,还好样例数据测出错误了。这说明再简单的水题,都要先拿样例数据测试一下,再去写。

2.逗号一开始写错了

3.数组设置为0后还有一些小问题,我也解决了。主要是go函数起始点的问题。


不得不说,这个go函数设计的非常巧妙,学习一个!

#include<bits/stdc++.h>
using namespace std;
int tt=0,n,k,m,ans1,ans2,leftt;//left代表目前还有几个元素(1-left)
int a[25];
int go(int start,int d,int step)//从start走step步,方向为d,逆时针为正,顺时针为负
{
    int xx=start-d;
    while(step)
    {
        //printf("xx=%d  step=%d\n",xx,step);
        xx=xx+d;
        if(xx==n+1)
            xx=1;
        if(xx==0)
            xx=n;
        if(a[xx]==0)
            continue;
        else
            step--;

    }
    return a[xx];
}
int main(void)
{
    while(scanf("%d%d%d",&n,&k,&m))
    {
        if((n==0)&&(k==0)&&(m==0))
            break;
        for(int i=1;i<=n;i++)
            a[i]=i;
        leftt=n;
        //printf("Stop 1\n");
        tt=0;
        ans1=1;
        ans2=n;
        while(leftt)
        {
            if(tt==0)
                tt++;
            else
                printf(",");
            ans1=go(ans1,1,k);
            ans2=go(ans2,-1,m);
            a[ans1]=a[ans2]=0;
            if(ans1==ans2)
            {
                leftt-=1;
                printf("%3d",ans1);
            }
            else
            {
                leftt-=2;
                printf("%3d%3d",ans1,ans2);
            }
        }
        printf("\n");
    }
    return 0;
}


版权声明:本文为fanesemyk原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。