1. 程式人生 > >UVa133救濟金的發放-約瑟夫環-自頂向下-雙向迴圈巧用對接

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");
    }
}