UVa133救济金的发放-约瑟夫环-自顶向下-双向循环巧用对接

应该算是比较水的模拟题,但刚开始做比较困难,用比较傻纯模拟还没做出来老是BUG,看了题解发现同样是模拟,应该先由顶向下分块,然后将需要的函数拿出来写会让整体结构更清晰。

其次,是关于怎样1到10到边界以后回到1,以及10到1到边界以后回到10的问题,题解中巧用了p=(p+d+n-1)%n+1,的方法,其实还是没搞明白为什么这样,但是也没有必要一定弄清缘由,这种循环模拟规律大同小异,记住这里相应的规律即可。

然后是关于逐步+1或者-1测试的问题,我之前的思维是用for()逐渐+1然后If()测试,太笨了,可以用whlie(l - -){ }。


#include <stdio.h>
#define maxn 23
int n;
int a[maxn]={0};
int leftn,k,m,a_1=1,a_2=-1;//1号逆序官员A+1,2号相反
int go(int p,int d,int l)
{
    while(l--)
    {
        do{p=(p+d+n-1)%n+1;}
        while(a[p]==0);
    }
    return p;
}
int main()
{
    while(scanf("%d%d%d",&n,&k,&m)==3&&n)
    {
        int p_1=n,p_2=1;
        leftn=n;
        for(int i=1;i<=n;i++)
            a[i]=i;
        while(leftn)
        {
            p_1=go(p_1,a_1,k);
            p_2=go(p_2,a_2,m);
            printf("%3d",p_1);
            leftn--;
            if(p_1!=p_2)
                {
                    printf("%3d",p_2);
                    leftn--;
                }
            a[p_1]=a[p_2]=0;
            if(leftn)
                printf(",");
        }
        printf("\n");
    }
}

你可能感兴趣的:(ACM,uva)