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 }