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