【STL+模拟】UVa 506 - System Dependencies
System Dependencies |
Components of computer systems often have dependencies--other components that must be installed before they will function properly. These dependencies are frequently shared by multiple components. For example, both the TELNET client program and the FTP client program require that the TCP/IP networking software be installed before they can operate. If you install TCP/IP and the TELNET client program, and later decide to add the FTP client program, you do not need to reinstall TCP/IP.
For some components it would not be a problem if the components on which they depended were reinstalled; it would just waste some resources. But for others, like TCP/IP, some component configuration may be destroyed if the component was reinstalled.
It is useful to be able to remove components that are no longer needed. When this is done, components that only support the removed component may also be removed, freeing up disk space, memory, and other resources. But a supporting component, not explicitly installed, may be removed only if all components which depend on it are also removed. For example, removing the FTP client program and TCP/IP would mean the TELNET client program, which was not removed, would no longer operate. Likewise, removing TCP/IP by itself would cause the failure of both the TELNET and the FTP client programs. Also if we installed TCP/IP to support our own development, then installed the TELNET client (which depends on TCP/IP) and then still later removed the TELNET client, we would not want TCP/IP to be removed.
We want a program to automate the process of adding and removing components. To do this we will maintain a record of installed components and component dependencies. A component can be installed explicitly in response to a command (unless it is already installed), or implicitly if it is needed for some other component being installed. Likewise, a component, not explicitly installed, can be explicitly removed in response to a command (if it is not needed to support other components) or implicitly removed if it is no longer needed to support another component. Installing an already implicitly-installed component won't make that component become explicity installed.
Input
The input will contain a sequence of commands (as described below), each on a separate line containing no more than eighty characters. Item names are case sensitive, and each is no longer than ten characters. The command names (DEPEND, INSTALL, REMOVE and LIST) always appear in uppercase starting in column one, and item names are separated from the command name and each other by one or more spaces. All appropriate DEPENDcommands will appear before the occurrence of any INSTALL command that uses them. There will be no circular dependencies. The end of the input is marked by a line containing only the word 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 |
Output
Echo each line of input. Follow each echoed INSTALL or REMOVE line with the actions taken in response, making certain that the actions are given in the proper order. Also identify exceptional conditions (see Sample Output, below, for examples of all cases). For the LIST command, display the names of the currently installed components in the installation order. No output, except the echo, is produced for a DEPEND command or the line containing END. There will be at most one dependency list per item.
Sample Input 1
DEPEND TELNET TCPIP NETCARD
DEPEND TCPIP NETCARD
DEPEND DNS TCPIP NETCARD
DEPEND BROWSER TCPIP HTML
INSTALL NETCARD
INSTALL TELNET
INSTALL foo
REMOVE NETCARD
INSTALL BROWSER
INSTALL DNS
LIST
REMOVE TELNET
REMOVE NETCARD
REMOVE DNS
REMOVE NETCARD
INSTALL NETCARD
REMOVE TCPIP
REMOVE BROWSER
REMOVE TCPIP
END
Sample Output 1
DEPEND TELNET TCPIP NETCARD
DEPEND TCPIP NETCARD
DEPEND DNS TCPIP NETCARD
DEPEND BROWSER TCPIP HTML
INSTALL NETCARD
Installing NETCARD
INSTALL TELNET
Installing TCPIP
Installing TELNET
INSTALL foo
Installing foo
REMOVE NETCARD
NETCARD is still needed.
INSTALL BROWSER
Installing HTML
Installing BROWSER
INSTALL DNS
Installing DNS
LIST
NETCARD
TCPIP
TELNET
foo
HTML
BROWSER
DNS
REMOVE TELNET
Removing TELNET
REMOVE NETCARD
NETCARD is still needed.
REMOVE DNS
Removing DNS
REMOVE NETCARD
NETCARD is still needed.
INSTALL NETCARD
NETCARD is already installed.
REMOVE TCPIP
TCPIP is still needed.
REMOVE BROWSER
Removing BROWSER
Removing HTML
Removing TCPIP
REMOVE TCPIP
TCPIP is not installed.
END
Sample Input 2
DEPEND A B
INSTALL A
INSTALL B
REMOVE A
END
Sample Output 2
DEPEND A B
INSTALL A
Installing B
Installing A
INSTALL B
B is already installed.
REMOVE A
Removing A
Removing B
END 前话:虽然划归到数据结构这一章,但还是一个需要熟练使用STL的模拟题;说实话代码是按照如家大神的思路来的,而且如果不看他的思路的话自己的条理也应该不会这么清晰吧...总之又学到了新的思路。学一点就得记住一点啊。 题意:软件组件之间会有依赖关系,比如你下一个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指令中删除。
最后就是注意字符串输入与输出的细节问题。 分析:
①输入问题:
注意输入的语句需要同一格式输出,所以需要用getline输入,对于语句中会出现空白符且需要提取子串,这里可以用到istringstream类(头文件sstream),其功能为从流中提取数据,支持>>操作,用法为:
#include<iostream>
#include<sstream>
using namespace std;
int main()
{
string str, line;
while(getline(cin, line))
{
istringstream stream(line);
while(stream>>str)
cout<<str.c_str()<<endl;
}
return ;
}
②细节问题:
首先,维护一个组建的名字列表——可以把输入中的组件名全部转化为整数编号。此处可以使用一个map记录出现过的组件名及其编号,使用字符串数组name方便记录编号对应的组件名。
int cnt;
int ID(string It)
{
if(item.count(It)) return item[It];
item[It] = ++cnt;
name[cnt] = It;
return cnt;
}
接下来用两个vector数组depend[x]和be_depended[x]分别表示组件x所依赖的组件列表和依赖于x的组件列表。这样就可以方便安装及删除组件。
if(com == "DEPEND")
{
line >> item1;
int id1 = ID(item1), id2;
while(line >> other)
{
id2 = ID(other);
depend[id1].push_back(id2);
be_depended[id2].push_back(id1);
}
}
为了区别显示安装还是隐式安装,需要一个status[x]数组,0表示组件x未安装,1表示显示安装,2表示隐式安装。
void install(int it, bool toplevel) //toplevel区分显、隐示安装
{
if(!status[it]) //status[x] = 0,组件x未安装
{
for(int i = ; i < depend[it].size(); i++)
{
install(depend[it][i], false); //所有依赖组件隐式安装,递归调用
}
cout << " Installing " << name[it] << endl;
status[it] = toplevel ? : ;
installed.push_back(it); //把已安装的组件加入到vector数组installed中
}
}
if(com == "INSTALL")
{
line >> item1;
int id = ID(item1);
if(status[id]) //若该组件已安装
cout << " " << name[id] << " is already installed." << endl;
else
install(id, true); //显式安装
}
而对于删除组件,首先判断组件能否删除,即是否被未删除的组件依赖,若能删除,在删除后再递归删除他所依赖的组件。
bool needed(int it)
{
for(int i = ; i < be_depended[it].size(); i++)
{
if(status[be_depended[it][i]]) return true; //组件被未删除组件依赖,
}
return false;
} void Remove(int it, bool toplevel)
{
if((toplevel || status[it] == ) && !needed(it))//若该组件显式卸载或它是隐身安装的,且不被依赖,则可以卸载
{
status[it] = ;
installed.erase( remove(installed.begin(), installed.end(), it), installed.end() ); //注意erase与remove结合的用法
cout << " Removing " << name[it] << endl;
for(int i = ; i < depend[it].size(); i++)
{
Remove(depend[it][i], false);
}
}
}
剩下的就是小意思了,LIST指令直接按编号输出name[]元素就好; AC代码如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<cctype>
#include<sstream>
using namespace std; const int maxn = ;
vector<int> depend[maxn], be_depended[maxn];
vector<int> installed;
map<string, int> item;
string name[maxn];
int status[maxn];
int cnt;
int ID(string It)
{
if(item.count(It)) return item[It];
item[It] = ++cnt;
name[cnt] = It;
return cnt;
} void install(int it, bool toplevel)
{
if(!status[it]) //status[x] = 0,组件x未安装;status[x] = 1,显示安装;status[x] = 2,隐式安装;
{
for(int i = ; i < depend[it].size(); i++)
{
install(depend[it][i], false); //隐式安装
}
cout << " Installing " << name[it] << endl;
status[it] = toplevel ? : ;
installed.push_back(it);
}
} bool needed(int it)
{
for(int i = ; i < be_depended[it].size(); i++)
{
if(status[be_depended[it][i]]) return true; //组件被其他组件依赖,
}
return false;
} void Remove(int it, bool toplevel)
{
if((toplevel || status[it] == ) && !needed(it))
{
status[it] = ;
installed.erase( remove(installed.begin(), installed.end(), it), installed.end() ); ///!!
cout << " Removing " << name[it] << endl;
for(int i = ; i < depend[it].size(); i++)
{
// cout << name[depend[it][i]] << endl;
Remove(depend[it][i], false);
}
}
} int main()
{
//freopen("in.txt", "r", stdin);
cnt = ;
string com, item1, other;
getline(cin, com);
while()
{
cout << com << endl;
istringstream line(com);
line >> com;
//cout << com << endl;
if(com == "END") break;
if(com == "DEPEND")
{
line >> item1;
int id1 = ID(item1), id2;
while(line >> other)
{
id2 = ID(other);
depend[id1].push_back(id2);
be_depended[id2].push_back(id1);
}
}
else if(com == "INSTALL")
{
line >> item1;
int id = ID(item1);
if(status[id])
cout << " " << name[id] << " is already installed." << endl;
else
install(id, true); //显式安装
}
else if(com == "REMOVE")
{
line >> item1;
int id = ID(item1);
if(!status[id])
cout << " " << name[id] << " is not installed." << endl;
else if(needed(ID(item1)))
cout << " " << name[id] << " is still needed." << endl;
else
Remove(id, true); //显式卸载
}
else if(com == "LIST")
{
for(int i = ; i < installed.size(); i++)
cout << " " << name[installed[i]] << endl;
}
getline(cin, com);
}
return ;
}
【STL+模拟】UVa 506 - System Dependencies的更多相关文章
- UVA 506 System Dependencies(模拟 烂题)
https://vjudge.net/problem/UVA-506 题目是给出了五种指令,DEPEND.INSTALL.REMOVE.LIST.END,操作的格式及功能如下: DEPEND item ...
- Uva - 506 - System Dependencies
模拟题,注意显示安装和隐式安装,显示安装的必须显示显示删除.把名字转化为整数维护.其他注意都注释了.输入稍微多一下,题目不是很麻烦. AC代码: #include <iostream> # ...
- UVa 506 System Dependencies (细节问题)
题意:输入几种指令,让你进行模拟操作,指令如下: DEPEND item1 item2 (item3 ...) 安装item1需要先安装item2(.item3……) INSTALL item1 安装 ...
- stl+模拟 CCF2016 4 路径解析
// stl+模拟 CCF2016 4 路径解析 // 一开始题意理解错了.... #include <iostream> #include <string> #include ...
- Learning ROS: Managing System dependencies
Download and install the system dependencies for turtlesim: roscd turtlesim cat package.xml rosdep i ...
- 【例题 6-21 UVA - 506】System Dependencies
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 记录每个物品它的依赖有哪些,以及它被哪些东西依赖就可以了. 显式安装的东西不能被隐式删除删掉(就是remove item,然后删除i ...
- UVA - 11995 - I Can Guess the Data Structure! STL 模拟
There is a bag-like data structure, supporting two operations: 1 x Throw an element x into the bag. ...
- uva 327 Evaluating Simple C Expressions 简易C表达式计算 stl模拟
由于没有括号,只有+,-,++,--,优先级简单,所以处理起来很简单. 题目要求计算表达式的值以及涉及到的变量的值. 我这题使用stl的string进行实现,随便进行练手,用string的erase删 ...
- STL——模拟实现空间配置器
目录 问题 SGI版本空间配置器-std::alloc 一级空间配置器 二级空间配置器 Refill.chunkAlloc函数 最后,配置器封装的simple_alloc接口 问题 我们在日常编写C+ ...
随机推荐
- POJ 3159 Candies (栈优化spfa)
Candies 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/J Description During the kinderga ...
- Java线程池学习
Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...
- codeforces 630B Moore's Law
B. Moore's Law time limit per test 0.5 seconds memory limit per test 64 megabytes input standard inp ...
- sublime text2 用ctags插件实现方法定位
sublime text2 用ctags插件实现方法定位(转) 我们用sublime几乎都会首先安装这个插件,这个插件是管理插件的功能,先安装它,再安装其他插件就方便了. 点击sublime的菜单栏 ...
- properties.load(in); 引出的中文乱码问题
/** * Reads a property list (key and element pairs) from the input byte stream. * The input stream i ...
- Java学习笔记(七):内部类、静态类和泛型
内部类 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来说包括这四种:成员内部类.局部内部类.匿名内部类和静态内部类.下面就先来了解一下这四种 ...
- Qt + CURL + mimetic 发送邮件(带附件)
使用了大名鼎鼎的CURL 开源库,以及mimetic开源库. CURL支持N多协议.功能超强,但是不能直接发邮件附件,需要自己拼mime.太麻烦,于是乎~~ mimetic主要用于构造邮件mimeti ...
- Maven最佳实践:管理依赖
From:http://juvenshun.iteye.com/blog/337405 Maven最佳实践:管理依赖 "If I have seen further it is by sta ...
- 测试URL有效性
方法一: #禁用滚动条 $ProgressPreference='silentlycontinue' Invoke-WebRequest "www.163.com" -UseBas ...
- Android应用之《宋词三百首》(二)
接上回,上回我们讲到MainActivity里面将所有的宋词标题和作者显示到界面的ListView中去,我们接下来的工作是通过点击ListView的Item跳转到ContentActivity里面去显 ...