华为机试-064-中等-HJ64.MP3光标位置


一、描述

MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。
现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:
歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。
光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。
在这里插入图片描述
其他情况下用户按Up键,光标挪到上一首歌曲;用户按Down键,光标挪到下一首歌曲。
在这里插入图片描述
2. 歌曲总数大于4的时候(以一共有10首歌为例):
3. 特殊翻页:屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。
在这里插入图片描述
一般翻页:屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。光标当前屏幕的最后一首歌时的Down键处理也类似。
在这里插入图片描述
其他情况,不用翻页,只是挪动光标就行。
数据范围:命令长度 1 ≤ s ≤ 100 ,歌曲数量 1 ≤ n ≤ 150
在这里插入图片描述

1.1、输入描述

输入说明:
1 输入歌曲数量
2 输入命令 U或者D

1.2、输出描述

输出说明
1 输出当前列表
2 输出当前选中歌曲

二、示例

2.1、示例1

输入:

10
UUUU

输出:

7 8 9 10
7

三、答案(java)

3.1、方法一

解题思路:

模拟整个过程处理。情况分为歌曲数小于等于4和大于4两种情况,每种情况都要考虑特殊翻页、一般翻页、其他。用n表示歌曲总数,first表示当前页面的第一首歌,num表示当前选中的歌。

算法流程:

当歌曲数小于等于4时:特殊向上翻页,移动光标到最后一首歌;特殊向上翻页,移动光标到第一首歌;一般向上翻页,光标向上移动一格;一般向下翻页,光标向下移动一格;
当歌曲数大于4时:特殊向上翻页,光标移动到最后一首歌,最后一页第一首歌为n-3;特殊向下翻页,光标移动到第一首歌,第一页第一首歌为1;一般向上翻页,光标向上移一格,当前页第一首歌和光标位置相同;一般向下翻页,光标向下移一格,当前页第一首歌位置也向下移一格;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            String cmd = sc.next();
            parseCmd(cmd, n);
        }
    }

    public static void parseCmd(String str, int n) {
        // 页面数据大小,默认4
        int pageSize = 4;
        // 页面的歌曲大小,最大为4
        if (n < pageSize) {
            pageSize = n;
        }
        // 根据指令移动current光标,可以当作歌曲编号
        int current = 1;
        // 记录光标在页面中的位置pageIndex,即歌曲编号
        int pageIndex = 1;
        for (int i=0; i < str.length(); i++) {
            // 上移
            if (str.charAt(i) == 'U') {
                // 特殊情况,当前光标在歌曲中第一首
                if (current == 1) {
                    // 从第一行上移,移动到最后的歌曲
                    current = n;
                    // 光标在页面的位置,
                    pageIndex = pageSize;
                    // 一般情况,即光标不在第一行
                } else {
                    // 光标上移
                    current--;
                    if (pageIndex != 1) {
                        pageIndex--;
                    }
                }
            } else {
                // 下移
                // 已经到最后一首歌曲,光标到第一首歌曲
                if (current == n) {
                    current = 1;
                    pageIndex = 1;
                } else {
                    // 非最后一行,则光标下移即可
                    current++;
                    if (pageIndex != pageSize) {
                        pageIndex++;
                    }
                }
            }
        }
        // 计算光标前后数字个数
        int next =  pageSize - pageIndex;
        int pre = pageSize - 1 - next;
        // 打印页面
        String page = "";
        // 从当前光标前一个元素开始向前打印
        for (int i = pre; i>0; i--) {
            page += (current-i) + " ";
        }
        page += current + " ";
        for (int i=1; i<=next; i++) {
            page += (current + i) + " ";
        }
        // 去除尾部空格
        page = page.substring(0, page.length()-1);
        System.out.println(page);
        // 打印当前光标
        System.out.println(current);
    }
}

在这里插入图片描述

四、答案(python 3)

4.1、方法一

保姆级别的代码分享,虽然不是很简洁。
刚开始思路根本不清晰,看了大佬们的解法自己重构了一个,几番调整总算全部通过,分享一下。
n<5的情况比较简单,只用确定光标位置,没有翻页操作,不做分析。
n>4的情况分析如下:
问题点:如果确定当前页面的 4 首歌-------只需要确定当前页面某一首歌的索引位置,就能确定整个页面的四首歌
问题点:如何确定光标位置--------光标始终在显示页面的某一首歌上,因此其取值范围可固定为:1,2,3,4
问题点:Up 操作在什么位置特殊--------当光标位于页面第1首歌时,Up操作会刷新页面歌曲,实现一般翻页;当显示1~4首歌且光标位于1时,Up操作实现特殊翻页,页面歌曲变为显示 n-3~ n 首歌,光标位置位置变为4
问题点:Down 操作在什么位置特殊--------当光标位于页面第4首歌时,Down操作会刷新页面歌曲,实现一般翻页;当显示 n-3~ n 首歌且光标位于4时,Down操作实现特殊翻页,页面歌曲变为显示 1~4 首歌,光标位置位置变为1
其他:当光标不处于以上情况时,Up 、Down 操作只会实现光标位置变化,当前页面的4首歌曲不会变化

#!/usr/bin/python
# -*- coding: UTF-8 -*-

while True:
    try:
        n = int(input())  # 储存歌曲总数
        s = input().strip()  # 储存操作
        l = []
        for i in range(1, n + 1):  # 建立歌曲列表(非必要,我这里是为了统一输出,完全可以不用列表直接输出)
            l.append(i)
        # 关键变量
        f = 1  # f 用于指示当前页面第1首歌曲的索引位置,即应对问题 1
        p = 1  # p 用于指示当前页面光标所在位置,即应对问题 2 ,一页最多显示4首歌,所以 p 的取值范围在 1,2,3,4 之中

        if n < 5:  # 第一种情况,歌曲总数最多一页,没有翻页操作,比较简单,实现方法很多,这里不做介绍
            for i in s:
                if i == 'U':
                    if p == 1:
                        p = n
                    else:
                        p -= 1
                if i == 'D':
                    if p == n:
                        p = 1
                    else:
                        p += 1
        # 第二种情况,歌曲总数多于一页,有翻页操作,详见代码注释
        else:
            for i in s:  # 依次遍历操作
                if i == 'U':  # 判断操作是否为 Up
                    if f == 1 and p == 1:  # 问题点3:特殊翻页处理;当且仅当,当前页面为歌曲1 2 3 4(f = 1)且光标位于位置 1(p = 1)时,从第一页翻到最后一页
                        f = n - 3  # 最后一页的4首歌为:n-3  n-2  n-1  n,因此 f = n-3
                        p = 4  # 特殊翻页过后,光标直接指向当前页面最后一首歌,即 p = 4
                    elif p == 1:  # 问题点3:一般翻页操作; 当光标位于当前页面第一首歌时,Up操作不会改变光标位置,即p=1不变,而向上翻页使得f = f-1
                        f -= 1
                    else:  # 问题点5:普通操作。当光标不在当前页面第一首歌时,Up操作只会改变光标位置(p = p-1),不会改变f
                        p -= 1
                if i == 'D':  # Down 操作同理,理解特殊翻页,一般翻页 f 和 p的取值即变化,即可进行
                    if f == n - 3 and p == 4:
                        f = 1
                        p = 1
                    elif p == 4:
                        f += 1
                    else:
                        p += 1

        for i in l[f - 1:f + 4 - 1]:  # 输出当前页,列表索引从0开始,因此变量 f 需要减 1
            print(i, end=' ')
        print()
        print(f + p - 1)

    except:
        break

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tzq@2018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值