1 /************************************************************************* 2 > File Name: 45_LastNumberInCircle.cpp 3 > Author: Juntaran 4 > Mail: JuntaranMail@gmail.com 5 > Created Time: 2016年09月04日 星期日 20时21分57秒 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <bits/stdc++.h> 10 11 using namespace std; 12 13 14 // 环形链表 15 int LastRemaining1(int n, int m) 16 { 17 if (n<1 || m<1) 18 return -1; 19 20 int i = 0; 21 22 list<int> numbers; 23 for (int i = 0; i < n; ++i) 24 numbers.push_back(i); 25 26 list<int>::iterator current = numbers.begin(); 27 while (numbers.size() > 1) 28 { 29 for (int i = 1; i < m; ++i) 30 { 31 current ++; 32 if (current == numbers.end()) 33 current = numbers.begin(); 34 } 35 list<int>::iterator next = ++current; 36 if (next == numbers.end()) 37 next = numbers.begin(); 38 39 --current; 40 numbers.erase(current); 41 current = next; 42 } 43 return *current; 44 } 45 46 // 数组模拟环 47 int LastRemaining2(int n, int m) 48 { 49 if (n<1 || m<1) 50 return -1; 51 52 int array[n]; 53 int i = -1; 54 int step = 0; 55 int count = n; 56 57 while (count > 0) 58 { 59 i ++; 60 if (i >= n) // 模拟环 61 i = 0; 62 if (array[i] == -1) 63 continue; 64 step ++; 65 if (step == m) 66 { 67 array[i] = -1; 68 step = 0; 69 count --; 70 } 71 } 72 int ret = i; 73 return ret; 74 } 75 76 // 数学解法 77 int LastRemaining3(int n, int m) 78 { 79 if (n<1 || m<1) 80 return -1; 81 82 int ret = 0; 83 for (int i = 2; i <= n; ++i) 84 ret = (ret + m) % i; 85 86 return ret; 87 } 88 89 int main() 90 { 91 int n = 100; 92 int m = 5; 93 94 int ret1 = LastRemaining1(n, m); 95 int ret2 = LastRemaining2(n, m); 96 int ret3 = LastRemaining3(n, m); 97 98 printf("ret1 is %d ", ret1); 99 printf("ret2 is %d ", ret2); 100 printf("ret3 is %d ", ret3); 101 102 return 0; 103 }