1. 程式人生 > >約瑟夫環高效陣列法

約瑟夫環高效陣列法

今天我老師給我講了一種新的解題方法

時間複雜度為o(kn),算是一種比較高效的方法

#include<stdio.h>
#define N 100

void solve(int man[],int people,int specing)
{
    int count=0,out=0,now=0,pre;
    while(out<people)
    {
        count++;
        if(count%specing==0)
        {
            printf("%5d",now+1);
            if(++out%10==0) putchar('\n');
            man[pre]=man[now];//將淘汰的這個人儲存的資訊(下一個人的編號)給前一個人
        }

        pre=now;
        now=man[now];//資訊迭代

    }
    if(out%10!=0) putchar('\n');
}
void main()
{
    int man[N],i,people,specing;
    printf("請輸入人數和報數:");
    scanf("%d%d",&people,&specing);
    
    for(i=0;i<people;i++)
        man[i]=(i+1)%people;//每個人儲存下一個人的資訊
    solve(man,people,specing);
}

首先我們假設有10個人,當數到3被淘汰

人數:0 1 2 3 4 5 6 7 8 9 用陣列儲存下一個人的資訊

資訊:1 2 3 4 5 6 7 8 9 0 當然,我們還要定義一個前一個人,實現資訊的更新,

這個演算法的好處就是能將已經淘汰的人排除在外,不再進行運算

比如,假設2已經被淘汰了,則2儲存的資訊(3)會給1

人數:0 1   3 4 5 6 7 8 9

資訊:1 3   4 5 6 7 8 9 0

當5被淘汰,同理它的資訊(6)給了4

人數:0 1   3 4   6 7 8 9

資訊:0 3   4 6   7 8 9 0

餘此類推