hdu1443 Joseph

Problem Description
The Joseph\\\\\\\'s problem is notoriously known. For those who are not familiar with the original problem: from among n people, numbered 1, 2, . . ., n, standing in circle every mth is going to be executed and only the life of the last remaining person will be saved. Joseph was smart enough to choose the position of the last remaining person, thus saving his life to give us the message about the incident. For example when n = 6 and m = 5 then the people will be executed in the order 5, 4, 6, 2, 3 and 1 will be saved.

Suppose that there are k good guys and k bad guys. In the circle the first k are good guys and the last k bad guys. You have to determine such minimal m that all the bad guys will be executed before the first good guy.
 
Input
The input file consists of separate lines containing k. The last line in the input file contains 0. You can suppose that 0 < k < 14.
 
Output
            The output file will consist of separate lines containing m corresponding to k in the input file.
 
Sample Input
3
4
0
 
Sample Output
5
30
 
自己沒做出來,看了網上的資料才弄出來,對大牛們表示由衷的敬佩,先看看代碼吧!
#include<iostream>
using namespace std;

bool Jos(int k,int m)
{
    int start = 0;   ///start用來標記第一個好人的編號
    int last = k-1;    ///last用來標記最後一個好人的編號

    int out;      ///出局的人的編號

    for(int i=2*k; i>k; i--)
    {
        out = (m-1)%i;
        if(out>=start&&out<=last)///出局的人在start和last之間則說明把好人殺了
        {                        ///此時說明不成立
            return false;
        }
        else  ///出局一個壞人之後需要更新start和last,爲什麼?一會兒講。
        {
            start = ((start - m)%i+i)%i;
            last = ((last - m)%i+i)%i;
        }
    }
    return true;
}

int main()
{
    int ans[15];
    for(int i=1;i<14;i++)
    {
        for(int j=1; ;j++)
        {
            if(Jos(i,j))
            {
                ans[i] = j;
                break;
            }
        }
    }
    int k;
    while(cin>>k)
    {
        if(0==k)
        {
            break;
        }
        else
        {
            cout<<ans[k]<<endl;
        }
    }
    return 0;
}
這裏其餘的地方都比較好理解,唯一需要費電腦筋的可能就是start和last的更新問題,爲什麼更新?這當中的過程又是什麼?我們那題目中給的n=6,m=5來說明
n=6的時候前三個人是好人,後三個人是壞人,從第一個好人開始報數(報數的時候都是從1開始,不過我們這裏1的編號是0),注意:紅色部分是好人
最開始:
數組編號:0  1  2  3  4  5
實際編號:1  2  3  4  5  6
第一次報數的時候,5被踢了出去,只剩下1 2 3 4 6還在,第二次報數的時候顯然得是編號爲5開始報數字1,所以第二次報數的時候應該是這樣:
數組編號:0  1  2  3  4
實際編號:6  1  2  3  4  
……
依次類推,直到只剩下1 2 3爲止。同時,通過紅色的數字,我們發現,每一次報數的時候,好人的範圍都變了(第一次報數好人編號是0  1  2,而第二次是1  2  3)。那麼每次變化都遵循什麼規律,通過總結是這個規律:start = ((start-m)%i+i)%i,last = ((last-m)%i+i)%i,其中i代表本次報數的總人數。(這裏像大牛們表示敬意,換成是我的話,我可能都總結不出這個公式)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章