- 題目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;
}