#include <stdio.h>
#define LOGI(format, ...){\
fprintf(stdout, format, __VA_ARGS__);\
fprintf(stdout, "\n");\
}
/**
*@brief Calculate the label of the person who is lastly be removed from the crowd.
*@param lastPerson receieve the label of the last removed person.
*@param count The size of the crowd.
*@param len The interval of removing person from one to another.
*@return true if success, else return false.
*@remark
*/
bool getLastPerson(unsigned int& lastPerson, unsigned int count, unsigned int len){
// It is meaningless, if there is no person in the crowd or the interval equal to zero.
if(0 == len || 0 == count){
return false;
}
// the label is zero, if there only one person in the crowd.
unsigned int label(0);
for(unsigned int i(2); i <= count; ++i){
label = (label + (len) % i ) % i;
}
lastPerson = label;
return true;
}
int main(int argc,char* argv[]){
unsigned int lastPerson(2), count(8), len(3);
if(getLastPerson(lastPerson, count, len)){
LOGI("The position of the last person is %d", lastPerson);
}
return 0;
}
/**
* for example, size of the crowd is five, and the interval is three.
* 0 1 2 3 4 | 0 1
* d 0 1 2 3 | 0 1
* d 0 1 2
* 0 1 d
* d 0
*Note that character 'd' represents that corresponding element in the previous line is be removed in the current action.
*After removing a element, the rest of elements are rearranged. The arrangement regulation is as follow:
*>Firstly place the elements sited on the left hand of the removed element on the tail of the previous line.
*>Secondly assign new labels started with zero and increased from left to right for the left hand elements.
*>thus, the left hand elements is the new line.
*Repeat these steps until there only one element in the new line.
*When the number of elements in the line reach to one, that element is the last person be removed and the label of that element always be zero.
*so the question becomes how to calculate the label of that element in the initial line.
*It is evident that the label of the element with cur_label in the current line can be calculated in the previous line by using following formulation:
* pre_label = (cur_label + (len % pre_count)) % pre_count, where pre_count represents the number of elements in the previous line.
*> In order to explanation, we call the element with label value of cur_label in the current line as element A, and the element with the label value of zero in the current line as element B.
*> Then the offset between element A and B equal to cur_label.
*> Note that the offset between A and B is an constant among adjacent lines.
*> Besides, the label of element B in the previous line can be calculated easyly by using following formulation:
*> len % pre_count
*> So, the label of element A in the previous line become:
*> (len % pre_count) + cur_label
*> because the result of the above formulation may exceed pre_count value, so it is necessary to restrict it in the range of pre_count.
*> And the final formulation become:
*> ((len % pre_count) + cur_label) % pre_count
*/
约瑟夫环
最新推荐文章于 2024-04-16 12:11:58 发布