• UVA


    /*
    法一:
      参考博客: http://blog.csdn.net/shihongliang1993/article/details/73559187
      
       此外,这个blog也是用集合做的,所不同的是,这个博客没用string类型的pair,而是用了两个pair元素组成的结构体:
       以及,下面这个blog的解法虽也为集合,本质上一样,但是没用到C++11的那么多特性,所以更容易理解
       http://www.cnblogs.com/windrises/p/4655736.html
    
    思路:
    	* 作者和书名的对应放到map里,可根据书名寻找作者;因为(先按作者,再按标题排序),想到将2个string构造为pair;
    	
    	* 因为有"No two books have the same title.",想到可以用set,来保存现在书架上可借的书,和已还未归架的书
    	
    	* 建立书名和作者关联的map,使得可通过书名找到作者
    	
    收获:
    	* 如何在 DevC++中,用C++11标准编译?
    	http://blog.csdn.net/qiqi123i/article/details/53150837
    	
    	* string 的 rfind函数:
    	http://blog.csdn.net/dqvega/article/details/6969373
    	
    	* lower_bound
    	http://blog.csdn.net/niushuai666/article/details/6734403
    	
    	* STL 中的 prev 用法(对随机迭代器进行一次减法)
    	http://blog.csdn.net/u013630349/article/details/47105319
    	
    	* C++中的 auto 用于自动类型推断
    	http://blog.csdn.net/huang_xw/article/details/8760403
    	
    	* make_pair函数
    	http://blog.csdn.net/yockie/article/details/6980692
    	也可以不用,但是,定义pair类型时,写法会更复杂
    	但是也有别的方法,例如此题,可以 typedef pair<string, string> P;
    	
    	* getline函数, getline(cin, s)常用于读取每行,存入字符串的情况(还可自己设定字符串结束符,不一定非要是回车符)
    	http://blog.sina.com.cn/s/blog_60263c1c0101ck25.html
    	
    	* C++11 的 range-based for loop 语法
    	http://blog.csdn.net/foruok/article/details/51593778
    	http://en.cppreference.com/w/cpp/language/range-for
    	
    	* C++ erase函数的几种语法
    	http://www.cnblogs.com/ylwn817/articles/1967689.html
    	
    	
    */




    #include <iostream>
    #include <set>
    #include <unordered_map>
    #include <string>
    using namespace std;
    
    int main()
    {
    	string s;
    	unordered_map <string, string> books;
    	set<pair<string, string>> CBB, TBR; // can be borrowed /  to be returned
    	while (getline(cin, s) && s != "END")
    	{
    		auto pos = s.rfind('"'); 
    		auto title = s.substr(0, pos + 1), author = s.substr(pos + 5);
    		books[title] = author;
    		CBB.insert(make_pair(author, title));
    	}
    	
    	while (getline(cin, s) && s != "END")
    	{
    		auto order = s.substr(0, 6);
    		if (order == "SHELVE")
    		{
    			for (auto&i : TBR)
    			{
    				auto pos = CBB.lower_bound(i);
    				if (pos == CBB.begin() || CBB.empty()) cout << "Put " << i.second << " first" << endl; //注意不要忘记,可借书的set为空的这种情况
    				else cout << "Put " << i.second << " after " << (*prev(pos)).second << endl;
    				CBB.insert(i);
    			}
    			cout << "END" << endl;
    			TBR.clear();
    		}
    		else
    		{
    			auto title = s.substr(7);
    			auto tp = make_pair(books[title], title);
    			if (order == "BORROW") CBB.erase(CBB.find(tp));
    			else if (order == "RETURN") TBR.insert(tp);
    		}		
    	}
    	return 0;
    }

    /*
      法二:
      法二是对每个书本,建立结构体,数据成员有作者和状态(1表示可外借,0表示已借出,-1表示已归还但未上架)
      
      之后,再建立书名和书结构体一一对应的map,和放姓名的容器vector
      
      对姓名vector设定一个排序标准,先按作者,再按标题,从小到大排;
      
      对于借书和还书,只是改变该书对应的status,而对于上架操作,则是查找name的依次顺序,如果要放的书是在name中排第一位的,输出 Put+那本书的资料,否则,要输出该书放到哪一本书后面
      
      该方法的好处:
      用了结构体以后,状态的切换就变得相当容易
      且书的上架操作,因为有了vector的自定义排序,便可知道该书是放第一位,还是放其他某书的后面,也就能知道以何种输出方式输出
      
      思路借鉴自:
      http://blog.csdn.net/a197p/article/details/43747539
    
    */

    #include <iostream>
    #include <vector>
    #include <map>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    struct Book
    {
    	string author;
    	int status;
    	Book(string a = "", int s = 1) : author(a), status(s)
    	{
    	}
    }; 
    
    map<string, Book> Books;
    vector<string> Titles;
    
    bool mycmp(const string &a, const string &b)
    {
    	if(Books[a].author != Books[b].author) return Books[a].author < Books[b].author;
    	return a < b; //先比作者,再比标题	
    }
    
    int main()
    {
    	Books.clear();
    	Titles.clear();
    	string s, x;
    	Book tp;
    	while (getline(cin, s) && s != "END")
    	{
    		int pos = (int)s.rfind('"');
    		string title = s.substr(0, pos + 1);
    		Titles.push_back(title);
    		tp.author = s.substr(pos + 5);
    		tp.status = 1; //标记状态为可借
    		Books[title] = tp; 
    	}
    	
    	sort(Titles.begin(), Titles.end(), mycmp);
    	
    	while (cin >> s && s != "END")
    	{
    		if (s == "BORROW")
    		{
    			getchar();
    			getline(cin, x);
    			Books[x].status = 0; //表示此书已被借走
    		}
    		else if (s == "RETURN")
    		{
    			getchar();
    			getline(cin, x);
    			Books[x].status = -1; //表示此书已还但未上架
    		}
    		else if (s == "SHELVE")
    		{
    			int i, j;
    			for (i = 0; i < (int)Titles.size(); i++)
    			{
    				if (Books[Titles[i]].status == -1)
    				{
    					for (j = i; j >= 0; j--)
    					if (Books[Titles[j]].status == 1)
    					{
    						break;
    					}
    					if (j == -1) cout << "Put " << Titles[i] << " first" << endl;
    					else cout << "Put " << Titles[i] << " after " << Titles[j] << endl;
    					Books[Titles[i]].status = 1; //最初写时,忘了把上架后的书,状态重置为可借,导致找了许久的错误 
    				}
    				
    			}
    			cout << "END" << endl;
    				
    		}
    	}
    	
    	return 0;
    }


  • 相关阅读:
    第一份随笔
    慢哈希算法
    彩虹表
    基于Wireshark验证网站口令认证传输方案
    electron学习笔记2
    基于原型的软件需求获取
    《小学四则运算练习软件》结对项目报告
    201571030109 小学四则运算练习软件项目报告
    201571030109 《构建之法》速读
    个人学期总结
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789421.html
Copyright © 2020-2023  润新知