HDU 1443解題報告

Joseph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1768    Accepted Submission(s): 1095


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
 

Source
 

Recommend
lcy

       這道題屬於一道比較經典的模擬題。但是如果方法選用不當,模擬的複雜度太高的話會導致TLE。。因此我們需要格外注意,降低模擬的複雜度。利用好取模的性質進行模擬。假設j是要數到的編號,那麼假設數到j這個數的人位置爲t,這個人被殺以後,我們需要進行的操作是將這個人後邊一直到末尾的編號都減1,相當於補充被殺的這個人的位置缺口。這時我們計算下一個被殺的人的位置。就是(t+j-1)%num(num表示總人數,這時的num是減去1之後的,因爲殺掉一個人num就要減1)。這個式子得出的位置結果就是下一個要被殺的人的位置。這個式子很巧妙。t是被殺的人的位置,而我們需要做的是將被殺的那個人之後的所有人的編號都減小1,那麼原先的(t+1)位置的人現在編號爲t,(t+2)位置的人現在爲(t+1),所以把當前的t位置當爲起始位置,以後的標號就爲0,1,2,3……j-1,總共j個人。所以用(t+j-1)%num就是下一個被殺人的位置。因而要掌握好這個式子表示的含義,也就能很方便的理解約瑟夫環的過程。這個式子比其他的模擬過程要簡潔的多,也可以較快的求出結果。 

      參考代碼:

#include<cstdio>
int a[15];
int main()
{
    int n;
    for(int i=1;i<=14;i++)
    {
        for(int j=i+1;;j++)
        {
            int num=2*i,t=j%num;  //num表示總人數,t表示被殺人的位置
            if(t==0) t=num;
            int cnt=0;
            while(t>i)  //因爲要保證i+1~2*i的人先被殺,所以被殺人的編號t要始終大於i,如果不大於i,則退出循環,那麼被殺的人的個數也就達不到i
            {
                num--;
                t=(t+j-1)%num;
                if(t==0) t=num;
                cnt++;             //cnt表示被殺的人的個數
            }
            if(cnt==i)
            {
                a[i]=j;
                break;
            }
        }
    }
    while(~scanf("%d",&n)&&n)
    {
        printf("%d\n",a[n]);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章