2011-09-01 08:11:03Morris

c108. Joseph

c108. Joseph

內容 :

有一個惡名昭彰的 故事:某部落酋長有n個俘虜(編號從1,2,3,……,n),他叫他們排成一個圈圈,然後開始數,第m 個人要被煮來吃掉(第一次從編號1的人開始數),按照此規則繼續下去,直到只剩下一個人,那一個人可以保留性命。例如:n=6, m=5則被吃掉的人的編號依序是5,4,6,2,3最號只有編號 1活了下來。Joseph 是個很聰明的人,他總是能挑到最後存留的位置,所以這件事才被披露出來。

現在假設共有2k個人,其中排在編號 1 到 k 的是好人,排在編號 k+1 到 2k 的是壞人,你的任務就是要找出一個最小的 m,使得在所有 k 個壞人被吃掉之前,沒有一個好人會被吃掉。

輸入說明 :

每行一個整數k(0<k<14), k=0 代表輸入結束。

輸出說明 :

根據輸入的 k,輸出 m

範例輸入 :

3
4
0

範例輸出 :

5
30

提示 :

* Luck 貓翻譯

出處 :

ACM 305


作法 : 模擬+建表

/**********************************************************************************/
/*  Problem: c108 "Joseph" from ACM 305                                           */
/*  Language: C                                                                   */
/*  Result: AC (444ms, 228KB) on ZeroJudge                                        */
/*  Author: morris1028 at 2011-09-01 07:59:04                                     */
/**********************************************************************************/


#include<stdio.h>
#include<stdlib.h>
int Judge(int n, int k, int m) {
    static int i, j, kp, tk, tmp, lave;
    static int pre, now, next[29];
    for(i = 1; i < n; i++)
        next[i] = i+1;
    next[n] = 1, pre = n, now = 1, lave = n;
    for(i = 1; i <= m; i++) {
        tmp = 0;
        tk = k%lave;
        if(tk == 0) tk = lave;
        for(j = now; tmp != tk-1; pre = j, j = next[j])
            tmp++;
        kp = j;
        next[pre] = next[kp], now = next[kp], lave--;
        if(kp <= m)    return 0;
    }
    return 1;
}
main() {
    int m, k, i, Ans[14];
    for(i = 1; i <= 13; i++) {
        k = i, m = k+1;
        while(1) {
            if(Judge(2*k, m, k))
                break;
            m++;
        }
        Ans[i] = m;
    }
        
    while(scanf("%d", &k) == 1 && k)
        printf("%d\n", Ans[k]);
    return 0;
}

上一篇:c107. Jack Straws

下一篇:c106. Simply Syntax