孩子们的游戏
程序员文章站
2024-01-03 18:46:34
...
题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)
Solution 1
//标志计算法
class Solution {
public:
int LastRemaining_Solution(int n, int m)
{
int state[n];
int cnt,cur=0;
fill(state,state+n,0);
for(int i=0;i<n-1;++i)
{
cnt=1;
while(cnt<=m)
{
if(!(i==0&&cnt==1))
{
while(state[(cur+1)%n]!=0)
cur=(cur+1)%n;
cur=(cur+1)%n;
}
++cnt;
}
state[cur]=1;
}
for(int i=0;i<n;++i)
if(state[i]!=1) return i;
return -1;
}
};
Solution 2
//模拟循环数组
class Solution {
public:
int LastRemaining_Solution(int n, int m)
{
if(n<=0) return -1;
if(n==1) return 0;
int state[n];
fill(state,state+n,0);
int count=n,cur=-1,step=0;
while(count>0)
{
++cur;
if(cur>=n) cur=0;
if(state[cur]!=0) continue;
++step;
if(step==m)
{
state[cur]=1;
step=0;
--count;
}
}
return cur;
}
};
Solution 3
可以采用循环链表: 原理和循环数组一样,当最后链表只剩下一个元素时,输出索引。