MP3光标位置——牛客

1 问题描述

MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:

  1. 歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。
    光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。
  2. 歌曲总数大于4的时候(以一共有10首歌为例):
    ① 特殊翻页:屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,
    用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。
    同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。
    ② 一般翻页:屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,
    用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。
    光标当前屏幕的最后一首歌时的Down键处理也类似 。
    ③ 其他情况,不用翻页,只是挪动光标就行。

2 思路分析

  • 当歌曲数目少于等于4,其只有一页。
    1.当当前是U操作时,分两种情况:① 光标指向第1首时,经过U操作得光标指向第n首;② 否则光标所在位置–。
    2.当当前是D操作时,分两种情况:① 光标指向第n首时,经过U操作得光标指向第1首;② 否则光标所在位置++。
  • 歌曲数目>4,大于1页。
    1.当当前是U操作时,分三种情况:①光标指向第1首且本页开始位置也为第1首时,经过U操作得光标指向第n首,光标所在页的页首为n-3;除第①种情况,若光标所在位置为其所在页的页首位置,光标随页首位置均–;③光标不在该页页首位置,光标所在位置–;
    2.当当前是D操作时,分三种情况:①光标指向第n首时且本页页首位置为n-3时,经过U操作得光标指向第1首,光标所在页的页首也指向第1首;除第①中情况,若光标所在位置为其所在页页尾位置(页首位置+3),光标随页首位置++,② ③光标不在该页页尾位置,光标位置所在位置++。

3 牛客链接:MP3光标位置OJ

4 代码实现

#include<iostream>
#include<string>
using namespace std;

//歌曲数目少于等于4,其只有一页。
//1.当当前是U操作时,分两种情况:光标指向第1首时,经过U操作得光标指向第n首;否则光标所在位置--。
//2.当当前是D操作时,分两种情况:光标指向第n首时,经过U操作得光标指向第1首;否则光标所在位置++。
void SingLess4(string str,int n)
{
    int cursor=1;       //初始光标位于第一首歌处
    
    for(int i=0;i<str.size();++i)
    {
        if(str[i]=='U')
        {
            if(cursor==1)
                cursor=n;
            else
                cursor--;
        }
        else if(str[i]=='D')
        {
            if(cursor==n)
                cursor=1;
            else
                cursor++;
        }
        else                   //输入的操作是错误的
            return;
    }
    
    //打印:页——1~n; 当前光标位置——cursor
    for(int i=1;i<=n;++i)
        cout<<i<<" ";
    cout<<endl<<cursor<<endl;
}

//歌曲数目>4,大于1页。
//1.当当前是U操作时,分三种情况:①光标指向第1首且本页开始位置也为第1首时,经过U操作得光标指向第n首,光标所在页的页首为n-3;除第①种情况,若光标所在位置为其所在页的页首位置,光标随页首位置均--;③光标不在该页页首位置,光标所在位置--;
//2.当当前是D操作时,分三种情况:①光标指向第n首时且本页页首位置为n-3时,经过U操作得光标指向第1首,光标所在页的页首也指向第1首;除第①中情况,若光标所在位置为其所在页页尾位置(页首位置+3),光标随页首位置++,② ③光标不在该页页尾位置,光标位置所在位置++。
void SingMore4(const string& str,const int& n)
{
    //初始页首为1,光标所在位置也为1.
    int cursor=1;
    int pagestart=1;
    
    for(int i=0;i<str.size();++i)
    {
        //上翻
        if(str[i]=='U')
        {
            if(cursor==1 && pagestart)     //光标指向:第一页,页首
            {
                cursor=n;
                pagestart=n-3;
            }
            else if(cursor==pagestart)     //光标指向:非第一页,页首
            {
                cursor--;
                pagestart--;
            }
            else                           //光标指向:某页,非页首位置
            {
                cursor--;         //不翻页
            }
        }
        //下翻
        else if(str[i]=='D')
        {
            if(cursor==n && pagestart==n-3) //光标指向:最后一页,页尾
            {
                cursor=1;
                pagestart=1;
            }
            else if(cursor==pagestart+3)    //光标指向:非最后一页,页尾
            {
                cursor++;
                pagestart++;
            }
            else                            //光标指向:某页,非页尾位置
            {
                cursor++;
            }
        }
        else
            return;
    }
    
    //打印:页——1~n; 当前光标位置——cursor
    for(int i=pagestart;i<=pagestart+3;++i)
        cout<<i<<" ";
    cout<<endl<<cursor<<endl;
}
int main()
{
    int n;
    string str;
    while(cin>>n>>str)
    {
        if(n<=4)
            SingLess4(str,n);
        else
            SingMore4(str,n);
    }
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值