题目链接:MP3光标位置_牛客题霸_牛客网 (nowcoder.com)
MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。
现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:
歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。
光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。
2. 歌曲总数大于4的时候(以一共有10首歌为例):
特殊翻页:屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。
其他情况,不用翻页,只是挪动光标就行。
数据范围:命令长度1\le s\le 100\1≤s≤100 ,歌曲数量1\le n \le 150\1≤n≤150
进阶:时间复杂度:O(n)\O(n) ,空间复杂度:O(n)\O(n)
输入说明:
1 输入歌曲数量
2 输入命令 U或者D
输出说明
1 输出当前列表
2 输出当前选中歌曲
输入:
10 UUUU输出:
7 8 9 10 7
这个题目我只能说,又臭又长,读起来太费劲了。它说的意思,就是给你歌曲的总数 n ,然后它会循环进行 上一首歌,下一首歌的切换,要求你在所有的操作完之后。输出当前所在的歌曲下标(从 1 开始)以及当前页面的歌曲。 那么首先要理解切换歌以及切换页面的含义, 切换歌就是下标 加一 ,或者减一 。
但切换页面比较特殊,当下标在 1 的时候,切上一首歌,它就换为最后一个页面,页面里的歌就是最后4首歌(这里前提是 歌曲数大于4);当下标在 n 的时候,切下一首歌,页面就换为第一个页面,页面里的歌就是前四首歌。只有这两种情况,是我们正常理解的那种切换页面,就是整个的切换, 而另一种情况的切换页面,就只是把歌曲下标变了一下(第一个下标加 1,最后一个下标加一),其他情况不用页面里的歌不变。
有了上面的思路理解,这个题就好做些了。首先维护一个数组,它就是歌单,然后维护一个下标,它负责指向当前的歌曲。 当歌曲大于4首的时候,从第一首歌变成最后一首歌,就在数组里放最后四首歌,从最后一首歌变成第一首歌时,就把数组里的歌放前四首。当指向歌曲的下标超过数组里最大的值时,就放当前歌曲以及前面的三首歌曲; 当指向歌曲的下标小于数组里最小的值时,就放当前歌曲以及后面的三首歌曲;最后输出歌单数组,以及指向歌曲的下标就好了。
其实我这是一种比较常规的方法,还有一种巧方法是,用两个指针,分别指向第一首歌和第4首歌(如果n <4 ,就是指向第n首歌),如果指向歌曲的下标从第一首变为最后一首,就把两个指针修改为最后四首,如果指向歌曲的下标从最后一首变为第一首,就把两个指针修改为前四首,如果指向歌曲的下标超出两个指针,就修改指针就好了,没有超出就不动。 最后输出指针里的歌曲下标就可以了。这个思路比我上面用的思路,代码量少了三分之一。
代码注释:
- import java.util.*;
- public class Main{
- public static void main(String[] args){
- Scanner scan = new Scanner(System.in);
- int n = scan.nextInt();
- String command = scan.next();
- int index = 1;
- int[] musics = new int[4];
- // 小于等于四首歌时,不用切换页面,或者说不用维护歌单数组
- if(n<= 4){
- for(int i=0;i< command.length();i++){
- if(command.charAt(i) == 'U'){
- index--;
- // 如果index 小于1 ,就跳到最后一首歌
- if(index == 0)
- index = n;
- }else{
- index++;
- if(index > n)
- index = 1;
- }
-
-
- }
- int value =1;
- for(int j=0;j
4) ;j++){ - musics[j] = value++;
- }
- // 最后输出数组里的值就好了
- for(int i=0;i< Math.min(n,4)-1;i++){
- System.out.print(musics[i]+" ");
- }
- System.out.println(musics[n-1]);
- System.out.println(index);
- return;
- }else{
- // 当歌曲数大于 4首时
- for(int i=0;i< command.length();i++){
- if(command.charAt(i) == 'U'){
- index--;
-
- if(index == 0){
- index = n;
- int value = index-3;
- // 如果从第一首歌跳到最后一首,就把数组更新为最后四首歌
- for(int j=0;j< 4 && value <= n;j++){
- musics[j] = value++;
- }
- }
- // 如果当前歌的下标,小于数组最小值,就放当前歌和后三首
- if(index < musics[0]){
- int value = index;
- for(int j=0;j< 4 && value <= n;j++){
- musics[j] = value++;
- }
- }
- // 切为下一首歌
- }else{
- index++;
- // 如果从最后一首歌切位第一首歌,就把数组里放前四首
- if(index > n){
- index = 1;
- int value = index;
- for(int j=0;j<4 && value<=n;j++){
- musics[j] = value++;
- }
- }
- //如果当前歌的下标,大于数组最大值,就放当前歌和前三首
- if(index > musics[3]){
- int value = index-3;
- for(int j=0;j<4 && value<=n;j++){
- musics[j] = value++;
- }
- }
-
-
- }
-
- }
-
- }
- for(int i=0;i< musics.length-1;i++){
- System.out.print(musics[i]+" ");
- }
- System.out.println(musics[musics.length-1]);
- System.out.println(index);
-
- }
- }