1. 题意:软件组件之间会有依赖关系,比如你下一个Codeblocks你也得顺带着把编译器给下上。你的任务是模拟安装和卸载软件组件的过程。有以下五种指令,如果指令为“END”则退出程序;若为以下四种指令,则分别作对应操作:
Command Syntax Interpretation/Response
DEPEND item1 item2 [item3 ...] item1 depends on item2 (and item3 ...)
INSTALL item1 install item1 and those on which it depends
REMOVE item1 remove item1, and those on which it depends, if possible
LIST

list the names of all currently-installed components

在INSTALL指令中提到的组件成为显示安装,这些组件必须用REMOVE指令显示删除。同样,被显示安装的组件直接或间接依赖的其他组件也不能在REMOVE指令中删除。最后就是注意字符串输入与输出的细节问题。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <bitset>
#include <cassert> using namespace std; const int maxn = ;
int cnt = ;
map<string, int> name2id; // 把名字转化为整数,方便处理
string name[maxn]; vector<int> depend[maxn]; // 组件x所以来的组件列表
vector<int> depended[maxn]; // 依赖于x的组件列表 int status[maxn]; // 0表示组件x未安装,1表示显示安装,2表示隐式安装
vector<int> installed; // 存放安装过的组件,安装过的就不要再安装了 // 把名字转化为整数维护
int ID(const string& item)
{
if (!name2id.count(item)) {
name[++cnt] = item;
name2id[item] = cnt;
}
return name2id[item];
} // 是否有组件依赖于item
bool needed(int item)
{
for (int i = ; i < depended[item].size(); i++) {
if (status[depended[item][i]]) {
return true;
}
}
return false;
} // 安装item,如果有依赖项,递归的继续安装
void install(int item, bool toplevel)
{
if (!status[item]) {
for (int i = ; i < depend[item].size(); i++) {
install(depend[item][i], false);
}
cout << " Installing " << name[item] << endl;
status[item] = toplevel ? : ;
installed.push_back(item);
}
} // 判断是否能删除,如果能,删除之后递归的删除其他所依赖的组件
void remove(int item, bool toplevel)
{
if ((toplevel || status[item] == ) && !needed(item)) {
status[item] = ;
installed.erase(remove(installed.begin(), installed.end(), item), installed.end());
cout << " Removing " << name[item] << endl;
for (int i = ; i < depend[item].size(); i++) {
remove(depend[item][i], false);
}
}
} // 按照安装顺序输出
void list()
{
for (int i = ; i < installed.size(); i++) {
cout << " " << name[installed[i]] << endl;
}
} int main()
{
ios::sync_with_stdio(false);
string line, cmd;
memset(status, , sizeof(status));
while (getline(cin, line)) {
cout << line << endl;
stringstream ss(line);
ss >> cmd;
if (cmd[] == 'E') {
break;
}
string item1, item2;
if (cmd[] == 'L') {
list();
}
else {
ss >> item1;
int i1 = ID(item1);
if (cmd[] == 'D') {
while (ss >> item2) {
int i2 = ID(item2);
depend[i1].push_back(i2);
depended[i2].push_back(i1);
}
}
else if (cmd[] == 'I') {
if (status[i1]) {
cout << " " << item1 << " is already installed.\n";
}
else {
install(i1, true);
}
}
else {
if (!status[i1]) {
cout << " " << item1 << " is not installed.\n";
}
else if (needed(i1)) {
cout << " " << item1 << " is still needed.\n";
}
else {
remove(i1, true);
}
}
}
} return ;
}

算法入门经典-第六章 例题6-21 SystemDependencies的更多相关文章

  1. 算法入门经典第六章 例题6-14 Abbott的复仇(Abbott's Revenge)BFS算法实现

    Sample Input 3 1 N 3 3 1 1 WL NR * 1 2 WLF NR ER * 1 3 NL ER * 2 1 SL WR NF * 2 2 SL WF ELF * 2 3 SF ...

  2. 算法入门经典-第七章 例题7-4-1 拓展 n皇后问题 回溯法

    实际上回溯法有暴力破解的意思在里面,解决一个问题,一路走到底,路无法通,返回寻找另   一条路. 回溯法可以解决很多的问题,如:N皇后问题和迷宫问题. 一.概念 回溯算法实际类似枚举的搜索尝试过程,主 ...

  3. 算法入门经典第七章 例题7-2-1 生成1-n的排列

    输入正数n,按字典序从小到大的顺序输出n个数的所有排列.两个序列的字典序大小关系等价于从头开始第一个不相同位置处的大小关系. 递归的边界应该很好理解吧,当集合s[]中没有一个元素的时候,按照上面的伪码 ...

  4. C#入门经典 第六章 委托

    C#入门经典 第六章 6.6 委托的声明非常类似于函数,但不带函数体,且要使用delegate关键字. 委托的声明指定了一个返回类型和一个参数列表. 在定义了委托后,就可以声明该委托类型的变量. 接着 ...

  5. C#入门经典第六章函数-2-委托

    委托:

  6. Oracle编程入门经典 第12章 事务处理和并发控制

    目录 12.1          什么是事务处理... 1 12.2          事务处理控制语句... 1 12.2.1       COMMIT处理... 2 12.2.2       RO ...

  7. Oracle编程入门经典 第11章 过程、函数和程序包

    目录 11.1          优势和利益... 1 11.2          过程... 1 11.2.1       语法... 2 11.2.2       建立或者替换... 2 11.2 ...

  8. Perl语言入门:第六章习题:处理用户所指定的名字并汇报相应的姓。

    37 print "\n----------------------------------_exercise_6_1--------------------------\n";  ...

  9. 算法竞赛入门经典_第二章:循环结构程序设计_上机练习_MyAnswer

    习题2-1 位数 输入一个不超过109的正整数,输出它的位数.例如12735的位数是5.请不要使用任何数学函数,只用四则运算和循环语句实现. #include<stdio.h> int m ...

随机推荐

  1. List 常用方法解析

    1.Count属性 (获得List中元素数目) 2.Add( ) 在List中添加一个对象的公有方法 3.AddRange( ) 公有方法,在List尾部添加实现了ICollection接口的多个元素 ...

  2. RN打包的那些坑儿

    Write By lz: Lz 寄语: RN虐我千百遍, 我待RN如初恋, 坑儿爬多了也就自然了 官方文档: http://reactnative.cn/docs/0.43/signed-apk-an ...

  3. 【转载】Java实现word转pdf

    最近遇到一个项目需要把word转成pdf,GOOGLE了一下网上的方案有很多,比如虚拟打印.给word装扩展插件等,这些方案都依赖于ms word程序,在java代码中也得使用诸如jacob或jcom ...

  4. OpenCV、OpenCL、OpenGL、OpenPCL

    对于几个开源库的总结,作为标记,以前看过,现在开始重视起来!更详细资料请移步 开源中国社区! 涉及:OpenCV,OpenCL,OpenGL,OpenPCL 截止到目前: OpenGL的最新版本为4. ...

  5. 离线安装ADT和sdk

    重装Eclipse.离线安装ADT.Android SDK 由于最新的ADT.Android SDK需要最新版本的Eclipse才能使用,我无奈的只好升级Eclipse.看看自己的Eclipse已经两 ...

  6. win 2016 添加系统组件注册表,

    Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ServerManager\ServicingS ...

  7. 企业级任务调度框架Quartz(3) 一个简单的Quartz 例子

    1. 一个简单的Quartz 工程     本示例应用比起众所周知的 System.out.println("Hello world from Quartz") 来还是要有趣些.当 ...

  8. python简单的输入与输出

    1 首先利用python完成简单的输出,运行如下: python和c语言类似,但又有所不同,python开发快,语言简洁,我是这样对比学的 输出:print+空格+'要输出的内容',一定要是英文状态下 ...

  9. priority_deque作为Timer时间队列底层容器的一些思考

    https://www.bbsmax.com/A/D854VkZxzE/ 设置底层容器可以分离出两个逻辑上独立的问题: >如何存储构成优先级队列(容器)的实际元素,以及>如何组织这些元素以 ...

  10. 训练1-U

    输入2个正整数A,B,求A与B的最小公倍数. Input 2个数A,B,中间用空格隔开.(1<= A,B <= 10^9) Output 输出A与B的最小公倍数. Sample Input ...