这里分享的是我对评论区其他人答案的理解以及官方给的答案的理解,因为我也是刚刚开始刷题的小白,发博客只是为了记录我的学习过程,如果有不对的地方欢迎指正,谢谢喽。
题目:
n
个人站成一排,按从 1
到 n
编号。
最初,排在队首的第一个人拿着一个枕头。每秒钟,拿着枕头的人会将枕头传递给队伍中的下一个人。一旦枕头到达队首或队尾,传递方向就会改变,队伍会继续沿相反方向传递枕头。
- 例如,当枕头到达第
n
个人时,TA 会将枕头传递给第n - 1
个人,然后传递给第n - 2
个人,依此类推。
给你两个正整数 n
和 time
,返回 time
秒后拿着枕头的人的编号。
方法1
首先我们要考虑两种情况 就是当n<time时 和当n>time时
- 当n>time 此时枕头并没有传到尾部 假设n=4 time=2
1-2-3-4
那么拿到枕头的人是 3也就是number=time+1
- 当n<time时
这时我们已经知道枕头已经传递过了尾部 从头传递到尾所用的时间是r=n-1 那么我们就要记录它是奇数次传递还是偶数次传递我们记为p p=time/r
并且求出完整传递后剩余的时间 就是剩余的不足以传递到尾的时间 也就是rtime=time%r
当p为偶数时 意味着剩余的时间内 枕头的传递方向是 顺序传递
即number=time+1
当p为奇数时 此时枕头的传递方向是逆向传递 那么拿到枕头的人的编号是
number=n-rtime
代码实现如下
if(n>time)
{
return time+1;
}else{
int r = n-1; //传递一轮所花的时间
int p = time/r; //传递的轮次
int rtime = time%r;
if(p%2==0) //偶数次传递
{
return time+1;
}else{
return n-rtime; //奇数次传递
}
}
方法2(官方答案)
time %= (n - 1) * 2;
return time < n ? time + 1 : n * 2 - time - 1;
这里来对代码进行解释
已知枕头从头传到尾所用的时间是 r = n-1 那么完整的从头到尾再到头所用的时间就是2r
time %= (n - 1) * 2;
求的就是一次完整的传递后所剩余的时间 也可以写成time = time % ((n-1)*2);
return time < n ? time + 1 : n * 2 - time - 1;
这一行代码是一个三目运算 主要解释n * 2 - time - 1 这一段
剩余的时间不满足于一次完整的传递 且 time>n 那么可知这一段是逆向传递 那么逆向传递的编号就是 number = n - (time - (n-1)) 就是剩余的时间 减去正向传递到尾所用的时间得出逆向传递的时间 再用人数减去这个时间就得出拿到枕头人的编号
整理可得number=n*2-time-1;