题解 | #MP3光标位置#

MP3光标位置

https://www.nowcoder.com/practice/eaf5b886bd6645dd9cfb5406f3753e15

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            int n = in.nextInt();
            String cmd = in.next();
            parseCmd(cmd, n);
        }
    }

    public static void parseCmd(String commands, int n) {
        int start = 1;
        int end = Math.min(n, 4);
        // 光标位置
        int index = 1;
        for (int i = 0; i < commands.length(); i++) {
            // 根据向上移动和向下移动的公式,光标位置的变化
            if (commands.charAt(i) == 'U') {
                
                index = (index - 1 - 1 + n) % n + 1;
            } else if (commands.charAt(i) == 'D') {
                index = index % n + 1;
            }
            // 判断滑动窗口的位置是否需要改变
            if (index < start) {
                // 光标在窗口之上
                start = index;
                end = start + 3;
            } else if (index > end) {
                // 光标在窗口之下
                end = index;
                start = end - 3;
            }
        }
        // 输出窗口内容
        for (int i = start; i <= end; i++) {
            System.out.print(i + " ");
        }
        System.out.println();
        // 打印当前光标
        System.out.println(index);
    }
}

代码是赋值,说一下那个公式吧:

这行代码是在处理一个特定的滑动窗口问题,其中光标可以在一个序列上向上移动。这个问题中的滑动窗口有固定的长度,这里是4。光标的位置用 cursor 变量表示,它代表窗口的当前起始位置。

让我们分解这行代码:

cursor = (cursor - 1 - 1 + windowSize) % windowSize + 1;
  1. cursor - 1:这部分代码将光标向前移动一个位置。假设 cursor 的初始值是1,表示窗口的起始位置在序列的第一个元素上。那么 cursor - 1 将会把光标移动到序列的开始位置之前。
  2. - 1:由于我们已经将光标移动到了开始位置之前,再减1将会把光标移动到一个无效的位置(即序列的开始之前)。这个操作是为了模拟向上移动一个位置的效果。
  3. + windowSize:由于我们有一个固定大小的窗口,这个操作是将窗口的长度加到光标的当前位置。这样做的目的是为了在取模运算后,光标能够回到窗口的有效位置范围内。
  4. % windowSize:取模运算是用来确保光标的位置不会超出窗口的长度。如果光标移动后的位置加上窗口长度超出了窗口的最后一个位置,取模运算将会把光标位置调整到窗口内的一个有效位置。
  5. + 1:最后,我们再加上1,这是因为我们希望光标始终位于窗口的第一个位置,而不是在窗口开始之前的位置。这样,光标就正确地向上移动了一个位置,并且仍然保持在窗口的起始位置。

举个例子,如果 windowSize 是4,cursor 的初始值是1,那么执行这行代码的过程如下:

  1. cursor - 1 将光标移动到位置0(序列开始之前)。
  2. 再减1,光标移动到位置-1(一个无效的位置)。
  3. + windowSize 将光标移动到位置3(因为4 - 1 + 4 = 7,超出了窗口长度,但光标仍然在窗口内)。
  4. % windowSize 确保光标位置在0到3之间,这里是3 % 4 = 3(已经是有效位置,无需改变)。
  5. + 1 将光标移动到位置4,这是窗口的下一个有效起始位置。

这样,光标就成功地向上移动了一个位置,同时保持在滑动窗口的范围内。

全部评论

相关推荐

不愿透露姓名的神秘牛友
11-27 10:52
点赞 评论 收藏
分享
10-30 10:16
南京大学 Java
永远的鹅孝子:给南大✌️跪了
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务