题目:http://poj.org/problem?id=3588
傻傻的移位题目中的assumption输入都满足,WA了好几次,其实就是个水题,坑点如下:
(1)任何时候downloading.size()都不能大于N (2)要判断要pause的是不是downloading或waiting的,不是就忽略 (3)要判断continue的是不是paused的,不是就忽略 (4)要判断finish的是不是downloading的,不是就忽略看到10万个命令,刚开始还encode/decode一下,WA了几次之后写烦了,直接上string,然后把上面这几个判断加上,没想到A了,真是个坑爹题,唯一值得做的地方就是可以练习template。。。
#include <iostream>
#include <string>
#include <set>
#include <functional>
using namespace std;
typedef set<string> TaskSet;
int N, M;
string IDLE;
bool ascendingOrder;
TaskSet downloading, waiting, paused, finished;
inline void addTask(const string& id)
{
if(downloading.size() < N) downloading.insert(id);
else waiting.insert(id);
}
inline string getWaitingTask()
{
string id = ascendingOrder ? *waiting.begin() : *waiting.rbegin();
waiting.erase(id);
return id;
}
template <class Iterator, class Comparator>
void collect(Iterator diter, Iterator deter,
Iterator witer, Iterator weter,
Iterator piter, Iterator peter,
Iterator fiter, Iterator feter,
Comparator comp)
{
string id;
while(diter != deter || witer != weter || piter != peter || fiter != feter){
id = IDLE;
if(diter != deter && comp(*diter, id)) id = *diter;
if(witer != weter && comp(*witer, id)) id = *witer;
if(piter != peter && comp(*piter, id)) id = *piter;
if(fiter != feter && comp(*fiter, id)) id = *fiter;
if(diter != deter && *diter == id){
cout << id << " downloading\n";
++diter;
}
else if(witer != weter && *witer == id){
cout << id << " waiting\n";
++witer;
}
else if(piter != peter && *piter == id){
cout << id << " paused\n";
++piter;
}
else{
cout << id << " finished\n";
++fiter;
}
}
}
int main()
{
ios::sync_with_stdio(false);
int test;
string s, t;
less<string> lessThan;
greater<string> largeThan;
for(cin >> test; test--; ){
cin >> N >> M;
//initialize
downloading.clear();
waiting.clear();
paused.clear();
finished.clear();
ascendingOrder = true;
//execute order
while(M--){
cin >> s >> t;
if(s[0] == 'S'){
ascendingOrder = t[0] == 'a';
continue;
}
if(s[0] == 'N') addTask(t);
else if(s[0] == 'P'){
if(downloading.find(t) != downloading.end()) downloading.erase(t);
else if(waiting.find(t) != waiting.end()) waiting.erase(t);
else continue;
paused.insert(t);
if(!waiting.empty() && downloading.size() < N) downloading.insert(getWaitingTask());
}
else if(s[0] == 'C'){
if(paused.erase(t)) addTask(t);
}
else{
if(downloading.erase(t)){
finished.insert(t);
if(!waiting.empty() && downloading.size() < N) downloading.insert(getWaitingTask());
}
}
}
//collect final state
if(ascendingOrder){
IDLE = "zzzzzzzzzzzz";
collect(downloading.begin(), downloading.end(),
waiting.begin(), waiting.end(),
paused.begin(), paused.end(),
finished.begin(), finished.end(),
lessThan);
}
else{
IDLE = "";
collect(downloading.rbegin(), downloading.rend(),
waiting.rbegin(), waiting.rend(),
paused.rbegin(), paused.rend(),
finished.rbegin(), finished.rend(),
largeThan);
}
cout << "\n";
}
return 0;
}