-
题目1540:麦霸
-
时间限制:1 秒
内存限制:128 兆
特殊判题:否
提交:75
解决:19
-
题目描述:
-
GrassLand酷爱K歌,俗称麦霸,每次去KTV他都会为自己点许多歌曲。
给定点唱机的操作序列,GrassLand希望知道他所点的每首歌曲将会在什么时间开始播放。
点唱机的操作主要是对点唱机已选列表的操作,包括:
1.top x,将已选列表中第x首歌曲,置于已选列表顶端。
2.delete x,将已选列表中第x首歌曲从已选列表中删除。数据保证前两种操作中的x不大于当时已选列表中歌曲的数目,已选列表头部的歌曲记为第一首。
3.add val flag,将一首长度为val(1<=val<=1000)的歌曲加入已选列表尾端,当flag为1时代表该首歌是GrassLand所点,为0时由他人所点。
点唱机每一秒的操作逻辑如下:
1.若当前没有歌曲正在播放,且已选列表不为空,则播放已选列表头部的歌曲,并将其从已选列表中删除;否则不进行任何操作。
2.响应用户的操作,并对已选列表进行相应操作。
3.若当前歌曲已经播放完毕,结束播放。注意,若一首长度为v的歌曲在时刻x时开始播放,则其播放时间为[x,x+v),也就是说,若没有其他操作发生,它会在时刻x+v-1时结束播放。
除此之外,点唱机还提供了一种,针对正在播放歌曲的操作:
1.cut,即设置当前正在播放的歌曲,在cut操作发生的时刻,播放完毕。若此时没有歌曲正在播放,则忽略该操作。
初始时为0时刻,点唱机没有正在播放的歌曲,已选列表为空。
-
输入:
-
输入包含多组测试用例,每组测试用例的开头为一个整数k(1<=k<=1000),代表共有k个点唱机操作。
接下去k行,每行描述一个操作,其格式为”t+如上四种操作中的一种“,t(1<=t<=1000000)表示该操作发生的时刻,如
3 top 2,表示在时刻3将已选列表中的第二首歌曲置顶。数据保证在一个时刻内仅一个操作,且输入数据按照t递增顺序给出。
-
输出:
-
对于每组测试用例输出若干行,代表GrassLand所点的歌曲开始播放的时间刻度(所有被正在播放过的歌曲),播放时间按照升序排列。
-
样例输入:
-
7 1 add 15 1 2 add 16 1 3 add 10 0 4 add 16 1 5 top 2 6 delete 3 7 cut
-
样例输出:
-
2 18
-
#include <stdio.h>
#include <vector>
#include <string.h>
#include <queue>
using namespace std;
struct Node
{
int Length;
int fav;
int beginTime;
int endTime;
};
queue<Node> gd;
int k,opTime;
char op[10];
void top(int num)
{
if(num == 1)
{
return;
}
queue<Node> temp,temp2;
int index = 0;
while(gd.size() && opTime >= gd.front().beginTime)
{
temp.push(gd.front());
gd.pop();
}
while(index < num - 1)
{
temp2.push(gd.front());
gd.pop();
index++;
}
Node tempNode = gd.front();
tempNode.beginTime = temp.back().endTime + 1;
tempNode.endTime = tempNode.beginTime + tempNode.Length - 1;
gd.pop();
index++;
while(gd.size())
{
temp2.push(gd.front());
gd.pop();
}
while(temp.size())
{
gd.push(temp.front());
temp.pop();
}
gd.push(tempNode);
while(temp2.size())
{
temp2.front().beginTime = gd.back().endTime + 1;
temp2.front().endTime = temp2.front().beginTime + temp2.front().Length - 1;
gd.push(temp2.front());
temp2.pop();
}
}
void deleteNode(int num)
{
queue<Node> temp;
int index = 0;
while(gd.size() && opTime >= gd.front().beginTime)
{
temp.push(gd.front());
gd.pop();
}
while(index < num - 1)
{
temp.push(gd.front());
gd.pop();
index++;
}
gd.pop();
while(gd.size())
{
if(temp.size())
{
gd.front().beginTime = temp.back().endTime + 1;
}
else
{
gd.front().beginTime = opTime + 1;
}
gd.front().endTime = gd.front().beginTime + gd.front().Length - 1;
temp.push(gd.front());
gd.pop();
}
while(temp.size())
{
gd.push(temp.front());
temp.pop();
}
}
void cut()
{
int Index = 0;
queue<Node> temp;
while(gd.size() && opTime >= gd.front().beginTime)
{
temp.push(gd.front());
gd.pop();
}
temp.back().endTime = opTime;
while(gd.size())
{
if(temp.size())
{
gd.front().beginTime = temp.back().endTime + 1;
}
else
{
gd.front().beginTime = opTime + 1;
}
gd.front().endTime = gd.front().beginTime + gd.front().Length - 1;
temp.push(gd.front());
gd.pop();
}
while(temp.size())
{
gd.push(temp.front());
temp.pop();
}
}
int main()
{
while(scanf("%d", &k) != EOF)
{
while(gd.size())
{
gd.pop();
}
int num;
int curTime = 0;
for(int i = 0; i < k; i++)
{
scanf("%d %s", &opTime, &op);
if(strcmp(op,"add") == 0)
{
Node temp;
scanf("%d %d", &temp.Length, &temp.fav);
if(gd.empty())
{
temp.beginTime = opTime + 1;
}
else if(opTime >= gd.back().endTime)
{
temp.beginTime = opTime + 1;
}
else
{
temp.beginTime = gd.back().endTime + 1;
}
temp.endTime = temp.beginTime + temp.Length - 1;
gd.push(temp);
}
else if(strcmp(op,"top") == 0)
{
scanf("%d", &num);
top(num);
}
else if(strcmp(op,"delete") == 0)
{
scanf("%d", &num);
deleteNode(num);
}
if(strcmp(op,"cut") == 0)
{
if(gd.size())
{
cut();
}
}
}
while(gd.size())
{
if(gd.front().fav == 1)
{
printf("%d\n", gd.front().beginTime);
}
gd.pop();
}
}
return 0;
}