Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 56348 | Accepted: 21526 |
Descriptionide
Inputspa
Outputcode
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 }