先说说面试题:
有n个人(比如8),站成一个环,从第1个人开始报数,报1,2,3,报到3的人退出,剩下人的还是一个环,继续报数,问最后一个人是开始的编号?
这个问题是我的面试题,我是不会的,只能用数组的形式做出来。今天看了看别人答的,基本都一样,理解的有点费劲。我用我的方式在梳理一遍。
比如先让这些人站成1排
0 1 2 3 4 5 6 7
2 3 4 5 6 7
0 1
这个是编号,按照题意,应该是2这个人出局,剩下的格局在写出来,2标红色已出局了
然后从编号3开始在重新数1,2,3然后到第5出局。在第二次开始数的 时候,是不是可以把3,4,5,6,7,0,1 看成0,1,2,3,4,5,6?
3变成0,4变成1,5变成2,6变成3等,如下面梳理
3, 4,5,6,7,0,1
0,1,2,3,4,5,6是不是这样?
可以符合整行的规律,上面的3 = (0 + 3)% 8 《数字8是人数,小括号中的3个报数次数,报1,2,3退出报了3个数》,下面的4 = (1 + 3)% 8等等1 = (6 + 3)% 8,这个规律是当少一个人的时候,新的编号下面一行如何对应原来的编号上面一行的方法。
刚才的面试题是有8个人,但是咱们反过来想一想,如果想在是7个人,编号是0,1,2,3,4,5,6,7,你也身在其中,不管你的编号是几,比如你是6,但是你想象一下,你们的队伍刚才是8个人,是玩报数游戏的时候,才少了一个,所以说你在8个人的时候的编号是多少呢,(6+3)8,你的编号是1。
比如玩游戏的时候,就剩下你一个人了,你是不是报数1,2,3一次你就被踢出了,但是你就是剩下的最后一个,所以你可以先推出,你在2个人的时候你的编号是多少呢,(0 + 3)% 2(2代表玩这个游戏的人数),所以你的编号是1,当2个人的时候你们的编号是0,1(1就是你),当3个人的时候你的编号是几呢?(1 + 3)% 3 ,还是1,当4个人的时候呢,(1 + 3)%4 ,是0,当5个人的时候,(0+3)%5,变成3了。
所以说你开始的编号为0
int index = 0;
for(int j = 2;j<=8;j++){
index = (index + 3) % j;
}