北大poj- 1012

Joseph

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 56348   Accepted: 21526

Descriptionide

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.

Inputspa

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.

Outputcode

The output file will consist of separate lines containing m corresponding to k in the input file.

Sample Inputblog

3
4
0

Sample Outputip

5
30

分析:
一、先推了下公式:設存在k個好人爲0,1,...,k-1;存在k個壞人k,k+1,...,2k;設x屬於天然數,則m屬於[k+1+2kx, 2k+2kx]。也就是說,m的【第一輪】命中必定在壞人段。(嘗試再推第二輪命中,可是沒有推出合適的公式)
二、這個題其實作了3次:
第一次用公式+打標籤的方式。發如今k>8時,要跑好久好久。
第二次用公式+循環鏈表的方式。發如今k>10時,要跑好久好久。
第三次,突然意識到,我只須要輸出k,而不須要輸出被踢掉的壞人序號,因此不須要維護壞人序號。那麼好比0,1,2,3,4,5的人,第一次被幹掉的是4,正常來講,隊伍就變成0,1,2,3,5。因爲不須要維護壞人的序號,那麼就能夠認爲隊伍爲0,1,2,3,4。
三、存一下每一個k對應的m值,poj的用例有重複。
 1 #include <stdio.h>
 2 
 3 typedef int BOOL;
 4 
 5 #define TRUE   0
 6 #define FALSE  1
 7 
 8 #define MAX_NUM 14
 9 
10 BOOL CheckM(int m, int k)
11 {
12     int i = 0, len = 2*k;
13     int badDead = 0;
14 
15     while(badDead < k)
16     {
17         i = (i+m-1)%len;
18         if(i < k) return FALSE;
19         len--;
20         i %= len;
21         badDead++;
22     }
23     return TRUE;
24 }
25 
26 int CalcM(int k)
27 {
28     int x, m = 0;
29 
30     for(x = 0; x < 10000000; x++)
31     {
32         for(m = k+1+2*k*x; m <= 2*k*x+2*k; m++)
33         {
34             if(TRUE == CheckM(m, k)) return m;
35         }
36     }
37     return 0;
38 }
39 
40 int main()
41 {
42     int k = 0;
43     int rst = 0;
44     int ans[MAX_NUM] = {0};
45 
46     while(1 == scanf("%d", &k) && k > 0)
47     {
48         if(ans[k] == 0)
49         {
50             rst = CalcM(k);
51             ans[k] = rst;
52         }
53         else
54         {
55             rst = ans[k];
56         }
57         printf("%d\n", rst);
58     }
59 
60     return 0;
61 }
相關文章
相關標籤/搜索