/* 分析可见小白书 P174,我的代码中也有部分的分析和解释 收获: 1. vector中,remove 和 erase 联合,用来删除指定的元素 某个blog上有言简意赅的一个用法的举例说明 ( 来自: http://www.cnblogs.com/warmbeast/p/5325874.html): vector<int> v; v.erase(remove(v.begin(),v.end(),99),v.end());//真的删除所有等于99的元素 此外,还要注意的是,unique 和 erase 也有类似的用法,因为 unique 的去重,也不是真正的去重,而是将重复元素移动到 vector 的后面 ( 这个要点,我在之前做题时也曾经遇到过,可看此链接: http://blog.csdn.net/mofushaohua_ln/article/details/77795409 ) */
/* 查阅过的网址汇总: 1. 关于 remove 和 erase: http://www.cnblogs.com/warmbeast/p/5325874.html http://lib.csdn.net/article/cplusplus/29700 http://blog.csdn.net/ozwarld/article/details/7761519 http://blog.csdn.net/yockie/article/details/7859330 2. sstream 用于 string 类的分离: http://blog.csdn.net/jibancanyang/article/details/43400009 http://blog.csdn.net/xiaogugood/article/details/21447431 */
#include <iostream> #include <cstring> #include <string> #include <map> #include <vector> #include <sstream> #include <algorithm> // remove()函数的头文件 #define rep(i, n) for ( int i = 0; i < (n); i++ ) using namespace std; const int N = 1e4; int cnt = 0; int status[N]; // 0 表示未安装, 1 表示显式安装, 2 表示隐式安装 string name[N]; map<string, int> name_id; vector<int> depend[N], depend2[N]; // depend[x] 和 depend2[x] 分别表示,x所依赖的组件,和依赖于x的组件列表 vector<int> installed; // 按照安装顺序,保存安装的所有组件 int ID ( const string& str) { if ( !name_id.count(str) ) { name[++cnt] = str; name_id[str] = cnt; } return name_id[str]; } bool needed (int item) { rep( i, (int)depend2[item].size() ) if ( status[depend2[item][i]] ) return true; return false; } /* type 表示安装类型,表明当前是显式安装,还是隐式安装 显式和隐式安装的定义,是我们人为去规定的,可以这么描述: 显式就是,INSTALL 指令直接指定安装的文件 隐式就是,非 INSTALL 指令直接指定安装的文件,而是在安装别的文件时,可能由于需要这个文件,所以需要隐式先安装它 两者的区别在于: 显式安装的组件,必须用 REMOVE 指令显式删除 被显式安装组件,所直接或间接依赖,进而被隐式安装的其他组件,不能在 REMOVE 指令中删除 */ void install ( int item, bool type ) { if ( !status[item] ) //未安装才安装,不重复安装 { rep (i, (int)depend[item].size()) install(depend[item][i], false); cout << " Installing " << name[item] << endl; status[item] = type ? 1 : 2; installed.push_back(item); } } /* 删除组件的前提: 如果要删除,首先肯定要满足,不可再有依赖它的组件 还需要满足,要么是通过 REMOVE 删除,要么是安装时隐式安装 ( 因而,删除 REMOVE 指令要求删除的组件时,如果不再被任何组件依赖,就会和要删除的组件,一起被删除 ) 有个一定要小心的小细节:显式安装的,必须被显式删除 ,不能被隐式删除 */ void remove ( int item, bool type ) { if ( ( type || status[item] == 2 ) && !needed(item) ) { status[item] = 0; installed.erase( remove (installed.begin(), installed.end(), item), installed.end() ); cout << " Removing " << name[item] << endl; rep( i, (int)depend[item].size() ) remove( depend[item][i], false ); } } // 按照安装顺序输出 void list () { rep ( i, (int)installed.size() ) cout << " " << name[installed[i]] << endl; } void solve () { string str, cmd; // cmd: command string s1, s2; memset ( status, 0, sizeof(status) ); while ( getline(cin, str) ) { cout << str << endl; stringstream ss (str); ss >> cmd; if ( cmd[0] == 'E' ) break; if ( cmd[0] == 'L') list(); else { ss >> s1; int i1 = ID (s1); if ( cmd[0] == 'D' ) { while (ss >> s2) { int i2 = ID (s2); depend[i1].push_back(i2); depend2[i2].push_back(i1); } } else if ( cmd[0] == 'I' ) { if ( status[i1] ) cout << " " << s1 << " is already installed." << endl; else install (i1, true); } else { if ( !status[i1] ) cout << " " << s1 << " is not installed." << endl; else if ( needed(i1) ) cout << " " << s1 << " is still needed." << endl; else remove (i1, true); } } } } int main () { solve(); return 0; }