约瑟夫环

#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
*/ 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值