北大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 }
相关文章
相关标签/搜索