孩子们的游戏(圆圈中最后剩下的数)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了孩子们的游戏(圆圈中最后剩下的数)相关的知识,希望对你有一定的参考价值。
题目描述:
每年六一儿童节,NowCoder都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为NowCoder的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到NowCoder名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?
解法一:
思路:
找规律。首先定义最初的n个数字(0,1,…,n-1)中最后剩下的数字是关于n和m的方程为f(n,m)。 在这n个数字中,第一个被删除的数字是(m-1)%n,为简单起见记为k。
* 那么删除k之后的剩下n-1的数字为0,1,…,k-1,k+1,…,n-1,并且下一个开始计数的数字是k+1。相当于在剩下的序列中,k+1排到最前面,从而形成序列k+1,…,n-1,0,…k-1。
* 该序列最后剩下的数字也应该是关于n和m的函数。由于这个序列的规律和前面最初的序列不一样(最初的序列是从0开始的连续序列),因此该函数不同于前面函数,记为f’(n-1,m)。最初序列最后剩下的数字f(n,m)一定是剩下序列的最后剩下数字f’(n-1,m),所以f(n,m)=f’(n-1,m)。接下来我们把剩下的的这n-1个数字的序列k+1,…,n-1,0,…k-1作一个映射,映射的结果是形成一个从0到n-2的序列:
k+1 -> 0
k+2 -> 1
…
n-1 -> n-k-2
0 -> n-k-1
…
k-1 -> n-2
把映射定义为p,则p(x)= (x-k-1)%n,对应的逆映射是p-1(x)=(x+k+1)%n,f’(n-1,m)= p-1 [f(n-1,m)]=[f(n-1,m)+k+1]%n。把k=m%n-1代入得到f(n,m)=f’(n-1,m)=[f(n-1,m)+m]%n。
我们把这种关系表示为:
0 n=1
f(n,m)={
[f(n-1,m)+m]%n n>1
public int LastRemaining_Solution(int n, int m) { if(n<1||m<1) return -1; if(m>=n) return -1; int last=0; for(int i=2;i<=n;i++){ last=(last+m)%i; } return last; }
解法二:
/* *用数组来模拟环,思路还是比较简单,但是各种下标要理清 */ public static int findLastNumber(int n,int m){ if(n<1||m<1) return -1; int[] array = new int[n]; int i = -1,step = 0, count = n; while(count>0){ //跳出循环时将最后一个元素也设置为了-1 i++; //指向上一个被删除对象的下一个元素。 if(i>=n) i=0; //模拟环。 if(array[i] == -1) continue; //跳过被删除的对象。 step++; //记录已走过的。 if(step==m) { //找到待删除的对象。 array[i]=-1; step = 0; count--; } } return i;//返回跳出循环时的i,即最后一个被设置为-1的元素 }
解法三:
public int LastRemaining_Solution(int n,int m){ if (m == 0 || n == 0) { return -1; } ArrayList<Integer> data = new ArrayList<Integer>(); for (int i = 0; i < n; i++) {//将所有的数都加入到一个数组中 data.add(i); } int index = -1; while (data.size() > 1) { // System.out.println(data); index = (index + m) % data.size(); // System.out.println(data.get(index)); data.remove(index); index--;//此处的索引为什么是减1呢?,因为开始的时候index就是-1,本身index+m就表示的是第m个数,当删除index数的时候,index-1+m任然表示下一个第m的数
}
return data.get(0); }
以上是关于孩子们的游戏(圆圈中最后剩下的数)的主要内容,如果未能解决你的问题,请参考以下文章