1 问题描述
MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:
- 歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。
光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。 - 歌曲总数大于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;
}