POJ1012 Joseph
题目来源:http://poj.org/problem?id=1012
题目大意:求解约瑟夫环问题(1-n个人站成一个圈,选择一个数k,首先从1开始数,第k个人被处决,然后再从下一个人开始数,第k个人被处决,如此循环)。假设环中由k个好人和k个坏人,前k为好人,后k为坏人。找出最小的m使得在有好人被处决前所有坏人都被处决掉。
输入:每行1个k(0<k<14),由0作为结束。
输出:对于每个k输出最小的m。
Sample Input
3 4 0
Sample Output
5 30
直接暴力做TLE了,看到Discuss里面说测试数据里有重复,每计算一个k将结果的m保存,下一次求k时只要查表即可。
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1012 Joseph 3 // Memory: 248K Time: 235MS 4 // Language: C++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <iostream> 8 9 using namespace std; 10 11 int result[13]; 12 int k, m; 13 14 //检验m是不是k的解 15 bool isSolution(int k, int m) { 16 int lastKilled = 0; 17 for (int i = 0; i < k; i++) { 18 int killed = (lastKilled + m - 1) % (2 * k - i); 19 if (killed < k) { 20 return false; 21 } else { 22 lastKilled = killed; 23 } 24 } 25 result[k-1] = m; 26 return true; 27 } 28 29 int main() { 30 while (true) { 31 cin >> k; 32 if (k == 0) { 33 break; 34 } 35 //查表 36 if (result[k - 1] != 0) { 37 cout << result[k - 1] << endl; 38 continue; 39 } 40 int m = k + 1; 41 while (true) { 42 if (isSolution(k, m)) { 43 cout << m << endl; 44 break; 45 } else { 46 m++; 47 } 48 } 49 } 50 return 0; 51 }
由于k的取值范围很小,更加水的方法是在本地把所有可能的输出求出来,然后直接查表输出...
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1012 Joseph 3 // Memory: 164K Time: 0MS 4 // Language: C++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <stdio.h> 8 int main() { 9 int k; 10 for(;;) { 11 scanf("%d",&k); 12 if (!k) 13 break; 14 switch (k) { 15 case 1:printf("2\n");break; 16 case 2:printf("7\n");break; 17 case 3:printf("5\n");break; 18 case 4:printf("30\n");break; 19 case 5:printf("169\n");break; 20 case 6:printf("441\n");break; 21 case 7:printf("1872\n");break; 22 case 8:printf("7632\n");break; 23 case 9:printf("1740\n");break; 24 case 10:printf("93313\n");break; 25 case 11:printf("459901\n");break; 26 case 12:printf("1358657\n");break; 27 case 13:printf("2504881\n");break; 28 } 29 } 30 return 0; 31 }