华为OJ(MP3光标移动)

描述:

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

 

现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:

  1. 歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。

光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。

其他情况下用户按Up键,光标挪到上一首歌曲;用户按Down键,光标挪到下一首歌曲。

  2. 歌曲总数大于4的时候(以一共有10首歌为例):

 

特殊翻页:屏幕显示的是第一页(即显示第1  4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。

一般翻页:屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。光标当前屏幕的最后一首歌时的Down键处理也类似。

其他情况,不用翻页,只是挪动光标就行。

 

题目类别: 字符串,循环,函数,指针
难度: 中级
分数: 100
运行时间限制: 无限制
内存限制: 无限制
阶段: 应聘考试
输入:

第一行输入参数为歌曲总数目M(0 < M < 255)

第二行输入为用户操作,D表示Down键,U表示UP,D和U可以随意组合。测试用例中用户的输入保证合法性,不需要校验;

例如:

10

DDDD

表示10首歌曲,用户按了4个Down键。

 

 

   
样例输入:
10
DDDD
样例输出:
2 3 4 5
5

华为OJ上原来是这样的,输出:2 3 4 5 5 

对这输出例子,真是哔了狗了,还要自己猜想才猜出来原来是上面的有个回车。。。。。


开始把这道题想的太简单,后来发现还是很多情况需要讨论的。


1 对于M<=4的情况:不存在翻页的情况,只需要记录MP3位置-pos,最后直接输出:1-M回车pos

2 对于M>4的情况:这个就有点麻烦咯。

先设置变量flag记录位置pos是否大于4或者小于M-3,因为如果光标只是在[1 4]或者[M-3 M]之间那么不需要翻页,flag正是记录这种情况,当pos=10或者pos=1时,需要重置p1,p2. 

剩下的情况就好办了,遇到U,指针p1 p2向前移动1,遇到D指针向后移动1.

#include<iostream>
#include<string>
using namespace std;
struct node
{
	int element;
	node* prev;
	node* next;
};

int main(void)
{	
	int n,pos=1,flag=0;
	string s;
	cin>>n>>s;
	node *pbegin=new node[n];	
	node *pend=pbegin+n-1;	
	pbegin->prev=pend;
	
	pbegin->next=pbegin+1;	
	pbegin->element=1;
	for(int i=1;i<n-1;i++)
	{
		(pbegin+i)->next=(pbegin+i+1);
		(pbegin+i)->prev=(pbegin+i-1);
		(pbegin+i)->element=i+1;
	}
	pend->prev=pbegin+n-2;//pend->prev=pend+n-2;如此低级错误。o(╯□╰)o
	pend->next=pbegin;
	pend->element=n;	
	
	node *p1=pbegin,*p2;
	if(n<=4)
		{
			p2=pend;
			for(int i=0;i<s.size();i++)
				if(s[i]=='U')
				{
					pos--;
					if(pos<1)
						pos+=n;
				}
				else if(s[i]=='D')
				{
					pos++;
					if(pos>n)
						pos-=n;
				}
		}					
	else
	{
		p2=pbegin+3;
		for(int i=0;i<s.size();i++)
			if(s[i]=='U')
			{
					pos--;					
					if(pos<1)
						pos+=n;	
					if(pos<n-3)
						flag=1;
					if(pos==n||!flag)
					{
						p2=pend;//真是个损shai!开始p1,p2颠倒了,注意输出从p1到p2
						p1=pend-3;
						flag=0;
					}
					else
					{
						p1=p1->prev;
						p2=p2->prev;
					}

			}
			else if(s[i]=='D')
			{

					pos++;
					if(pos>n)
						pos-=n;					
					if(pos>4)
						flag=1;
					if(pos==1||!flag)
					{
						p1=pbegin;
						p2=pbegin+3;
						flag=0;
					}
					else
					{
						p1=p1->next;
						p2=p2->next;
					}

			}
	}
		for(node* i=p1;i!=p2;i=i->next)
			cout<<i->element<<" ";
		cout<<p2->element<<endl;		
	cout<<pos;
	delete [] pbegin;
	//system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值