zoukankan      html  css  js  c++  java
  • 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;
    }


  • 相关阅读:
    POJ 1300 Open Door
    POJ 2230 Watchcow
    codevs 1028 花店橱窗布置
    codevs 1021 玛丽卡
    codevs 1519 过路费
    codevs 3287 货车运输
    codevs 3305 水果姐逛水果街二
    codevs 1036 商务旅行
    codevs 4605 LCA
    POJ 1330 Nearest Common Ancestors
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789421.html
Copyright © 2011-2022 走看看