0%

算法竞赛入门经典(第2版) 5-8UVa230 - Borrowers

//又开学啦,不知不觉成为大二的老人了。。。时间过得好快啊,感觉好颓废。。。 题意:建立一个借书/归还系统。有借、还、把还的书插到书架上这三个指令。


代码:(Accepted, 0ms)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//UVa230 - Borrowers
#include<iostream>
#include<string>
#include<map>
#include<set>
using namespace std;

struct BOOK {
string au, ti;
BOOK(const string& a, const string& t) :au(a), ti(t) {}
BOOK() :ti("X"), au("X") {}
bool operator <(const BOOK &that)const {
if (au == that.au) return ti < that.ti;
return au < that.au;
}
};
map<BOOK, bool> list;//int:0在书架 1已经借出
map<string, BOOK> auth;
set<BOOK> ret;//归还列表
string tmp;

void B(const string& t) {
list[auth[t]] = true;
}

void R(const string& t) {
auto f = list.find(auth[t]);
ret.insert(f->first);
}

void S() {
for (auto& r : ret) {
cout << "Put " << r.ti;
auto re = list.find(r),p=re;
//if (re == list.end()) cout << "FUCK!\n";//
while (p != list.begin() && (--p)->second);
//cout << "喵喵喵?????\n";//
if (p == list.begin() && p->second) cout << " first\n";
else cout << " after " << p->first.ti << '\n';
re->second = false;
}
cout << "END\n";
ret.clear();
}

int main()
{
//freopen("in.txt", "r", stdin);
while (getline(cin, tmp) && tmp[0] != 'E') {
size_t n = tmp.rfind('\"');
string ti(tmp.substr(0, n + 1));
string au(tmp.substr(n + 5, tmp.size() - n - 6));
list[BOOK(au, ti)] = false;
auth[ti] = BOOK(au, ti);
}
//for (auto&r : list) cout << "--" << r.first.ti << '\t' << r.first.au << endl;//
while (getline(cin, tmp) && tmp[0] != 'E') {
if (tmp[0] == 'B') B(tmp.substr(7));
else if (tmp[0] == 'R') R(tmp.substr(7));
else S();
}
return 0;
}

分析:使用了STL的map和set。一个map存放所有书(书的作者与标题作为key,借阅/归还状态为value),一个map用来从标题映射到书的信息(因为下面borrow和return指令里不带作者信息,映射一下方便,但我内心还是不大情愿。的确有更好的方法,我不大会,下面再讲。)还有一个set存储归还了但还未放回书架的书。其他没啥要说的。

本来想将key设为标题,value设为作者的,但是不知道如何将map按value排序。查了查要用到vector+pair 中转,好像有点烦啊。但是网上看到这个,http://blog.csdn.net/a197p/article/details/43747539 。他就是采用了

1
2
3
4
5
struct book{  
string author;
int status;
};
map<string, book> books;

来存储。我还以为他能给map按照value重排,结果他建立了个vector< string > name; 来存放标题,存放顺序用以下方法

1
2
3
4
bool compare(string a, string b){  
if(books[a].author == books[b].author) return a < b;
else return books[a].author < books[b].author;
}

原来是稍微绕了一下,但是也不错耶。