题目:0,1,2,...,n-1这n个数字排成一个圈,从数字0开始每次从这个圆圈中删除第m个数字。求出这个圆圈里剩下的最后一个数字。
分析:利用环形链表模拟圆圈。总共有n个结点,每次都在这个链表中删除第m个结点。实现如下:
int LastRemaining(unsigned int n,unsigned int m)
{
if(n<1||m<1)
return -1;
unsigned int i=0;
list<int> numbers;
for(i=0;i<n;i++)
number.push_back(i);
list<int>::iterator current=numbers.begin();
while(numbers.size()>1)
{
for(int i=1;i<m;i++)
{
current++;
if(current==numbers.end())
current=numbers.begin();
}
list<int>::iterator next=++current;
if(next==numbers.end())
next=numbers.begin();
--current;
numbers.erase(current);
current=next;
}
return *(current);
}另一种简洁的方法,通过观察发现规律。设f(n,m)表示每次在n个数字中每次删除第m个数字最后剩下的数字。发现规律f(n,m)=[f(n-1,m)+m]%n,n>2.n=1时,f(n,m)=0.因此实现如下:
int LastRwmaining(unsigned int n,unsigned int m)
{
if(n<1||m<1)
return -1;
int last=0;
for(int i=2;i<=n;i++)
last=(last+m)%i;
return last;
}
















