这个题我用了三个map表,就是下面三个(~orz,看起来有点多):
typedef pair<string, string> PLL; //作者,书名
map<PLL, int> s; //图书馆的所有书,value为0表示已借,为1表示未借
map<string, string> d; //一个索引 d[书名] = 作者名
map<PLL, int> re; //表示目前归还,还未上书架的书。
首先解释一下为什么要使用pair<string, string>
,这是为了简单,题目要求图书的排序方法是先按作者从大到小,再按标题从小到到排。所以我们把作者设置为pair的第一个元素,书名设置为第二个元素。这样一来我们使用map<PLL, int>
来存储所有数据,map就会自动按照上面那个顺序排好。
(这是因为map自动对key进行排序,而我们这个的key为pair类型,pair类型比较时有个特点,就是先比较第一个元素,若一样再比较第二个元素。这个pair中的元素全为string类型,string类型有自定义好的比较运算符,所以这样一来我只须往map表中存元素就行,不用担心顺序问题)
接下来是main函数 :
int main() {
string buf;
while(getline(cin, buf) && buf != "END") {
size_t a = buf.find("by");
PLL p = make_pair(buf.substr(a), buf.substr(0, a-1));
s[p] = 1;
d[buf.substr(0, a-1)] = buf.substr(a);
}
string str1, str2;
while(getline(cin, str1) && str1 != "END") {
if(str1[0] == 'S') { //基本思路:遍历所有书籍
map<PLL, int>::iterator it = s.begin();
PLL p = make_pair(" ", " "); //设置p为待放入书的前一本书
while(it != s.end()) {
if(it->second) { //若这本书未借出,将这本书设置为待放入书籍的前一本书
p = it->first; it++;
continue;
}
if(re.count(it->first)) {
it->second = 1;
if(p.first == " ") cout << "Put " << it->first.second << " first" << endl;
else cout << "Put " << it->first.second << " after " << p.second << endl;
re.erase(it->first); //每放好一本书,就要把这本书从re表中删除
p = it->first; //放好之后这本书就成了下一本待放入书籍的前一本书了
it++; continue;
}
it++; //执行到这里说明这本书还未归还
}
cout << "END" << endl;
} else {
size_t a = str1.find(" ");
str2 = str1.substr(a+1);
str1 = str1.substr(0, a);
PLL p = make_pair(d[str2], str2);
if(str1[0] == 'B') s[p] = 0; else re[p] = 1;
}
}
return 0;
}
唯一麻烦点的就是SHELVE时,我们遍历所有书籍时总是得记录其前一本书籍是什么。这要这里处理好了就能AC了。