1.题目描述:点击打开链接
2.解题思路:也是模拟题意,不过过程比较复杂;还好调试后一次AC了,不过当看到别人的代码时,无奈了。长度不到我的一半。。。仔细分析了参考代码,发现有如下值得学习的地方:1,巧用结构体,把borrowed,returned当做一本书的成员;2.利用stable_sort分别对作者和书名进行排序(这个我还真不会(⊙o⊙))3;把定义好的book当做模板运用到vector中,结合了vector的优点;判断书本的情况只需要看returned,borrowed的状态即可,大大简化了程序结构,很值得学习啊!
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<cassert> #include<cstdlib> #include<ctime> #include<cmath> #include<cstring> #include<functional> using namespace std; const int maxn = 10000 + 10; map<string,int>IDcache; //记录作者的ID vector<string>auth; //存放每个作者的名字 vector<string>book[maxn];//每个作者自己的书 vector<int>shelf[maxn]; //模拟书架上的书籍 vector<int>back[maxn];//存储归还的书的位置 vector<int>borrow[maxn];//存放借走的书的位置 int arr[maxn]; //存放排序后的作者ID的编号 int len; //存放arr数组的长度 int ID(string&str)//给每个作者分配一个ID { if (IDcache.count(str)) return IDcache[str]; auth.push_back(str); return IDcache[str] = auth.size() - 1; } void find_book(string s, int&p,int&h)//寻找书的位置,第p个作者的第h本书 { for (p = 0; p < len;p++) for (h = 0; h < book[p].size();h++) if (book[p][h] == s) return; } void take_away(int p, int h) { borrow[p].push_back(h); shelf[p][h] = 0; } void bring_back(int p, int h) { back[p].push_back(h); sort(back[p].begin(), back[p].end()); for (int i = 0; i < borrow[p].size();i++) if (borrow[p][i] == h) { borrow[p].erase(borrow[p].begin() + i); //删除借书的记录 break; } } void before(int&p, int&h)//寻找它的前一本书的位置 { int m = p, n = h; if (p == 0 && h == 0) return; for (;;) { if (h == -1) { p--; h = shelf[arr[p]].size() - 1; } if (p == 0 && h == 0) if (shelf[arr[p]][h] > 0) return; else { p = m; h = n; return; } if (shelf[arr[p]][h] > 0)return; h--; } } void print() { for (int i = 0; i < len; i++) if (!back[arr[i]].empty()) { int p, h; int len = back[arr[i]].size(); for (int j = 0; j <len; j++) { p = i; h = back[arr[i]][j]; before(p, h); if (p == i&&h == back[arr[i]][j])没找到前一本书,说明这是第一本书 cout << "Put " << book[arr[p]][h] << "first" << endl; else cout << "Put " << book[arr[i]][back[arr[i]][j]] << "after " << book[arr[p]][h].substr(0, book[arr[p]][h].length() - 1) << endl; shelf[arr[i]][back[arr[i]][j]] = 1; } back[arr[i]].clear();//该作者的所有书归还后清空归还记录 } cout << "END" << endl; } int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); string line; while (getline(cin, line) && line != "END") { stringstream ss(line); string buf; string st,sr; while (ss >> buf) { if (buf == "by")break; st += buf; st += " "; } while (ss >> buf) sr += buf; book[ID(sr)].push_back(st); } len = auth.size(); sort(auth.begin(), auth.end());//对作者进行排序 memset(arr, 0, sizeof(arr)); for (int i = 0; i < len; i++) arr[i] = IDcache[auth[i]]; for (int i = 0; i < len; i++) sort(book[i].begin(), book[i].end());//对每个作者的书进行排序 for (int i = 0; i < len;i++) for (int j = 0; j < book[i].size(); j++) shelf[i].push_back(1);//判断书架上书的状态 string s1, s2; while (getline(cin,line)) { stringstream ss(line); string ct,s1,s2; while (ss >> ct) { s1 = ct; break; } while (ss >> ct) { s2 += ct; s2 += " "; } int p,h; if (s1[0] == 'S') print(); find_book(s2, p,h); if (s1[0] == 'B') take_away(p,h);//借书 if (s1[0] == 'R') bring_back(p,h);//还书 if (s1[0] == 'E')break; } return 0; }
(参考代码)长度是我的一半,但写的非常精彩,值得学习的地方特别多。
#include<cstdio> #include<cctype> #include<cstring> #include<iostream> #include<algorithm> #include<vector> using namespace std; class book //定义结构体book { public: book( string t, string a ) { author = a; title = t; borrowed = returned = false; } bool borrowed, returned;//把borrowed,returned当做书本的成员 string author, title; }; vector<book> all; string in, command, req; void shelve(), borrow(), back(); bool cmpa( book a, book b ){ return ( a.author < b.author ); }//按照作者排序 bool cmpt( book a, book b ){ return ( a.title < b.title ); }//按照书名排序 int main() { while( getline( cin, in ) && in != "END" ) all.push_back( book( in.substr( 0, in.find_last_of( "\"" ) + 1 ), in.substr( in.find_last_of( "\"" ) + 1 ) ) ); stable_sort( all.begin(), all.end(), cmpt );//分别对两种情况进行排序 stable_sort( all.begin(), all.end(), cmpa ); while( cin >> command ) if( command == "BORROW" ) cin.get(), borrow(); else if( command == "RETURN" ) cin.get(), back(); else if( command == "SHELVE" ) cin.get(), shelve(); } void shelve() { for( int i = 0, j; i < all.size(); ++i ) if( all[ i ].returned == true )//书本已经归还 { for( j = i; j >= 0; --j ) if( all[ j ].borrowed == false )//找到待放回书架的书的前一本书的位置 break; if( j == -1 ) printf( "Put %s first\n", all[ i ].title.c_str() );//转换成标准C输出 else printf( "Put %s after %s\n", all[ i ].title.c_str(), all[ j ].title.c_str() ); all[ i ].borrowed = all[ i ].returned = false;//放回后,将状态重置 } cout << "END\n"; } void borrow() { getline( cin, req ); for( int i = 0; i < all.size(); i++ ) if( all[ i ].title == req ) { all[ i ].borrowed = true; return; } } void back() { getline( cin, req ); for( size_t i = 0; i < all.size(); i++ ) if( all[ i ].title == req ) { all[ i ].returned = true; return; } }