题目来源: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 }