【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 (DEPENDINSTALLREMOVE 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),其功能为从流中提取数据,支持>>操作,用法为:
 1 #include<iostream>
 2 #include<sstream>
 3 using namespace std;
 4 int main()
 5 {
 6     string str, line;
 7     while(getline(cin, line))
 8     {
 9         istringstream stream(line);
10         while(stream>>str)
11             cout<<str.c_str()<<endl;
12     }
13     return 0;
14 }
②细节问题:首先,维护一个组建的名字列表——可以把输入中的组件名全部转化为整数编号。此处可以使用一个map记录出现过的组件名及其编号,使用字符串数组name方便记录编号对应的组件名。
1 int cnt;
2 int ID(string It)
3 {
4     if(item.count(It)) return item[It];
5     item[It] = ++cnt;
6     name[cnt] = It;
7     return cnt;
8 }
接下来用两个vector数组depend[x]和be_depended[x]分别表示组件x所依赖的组件列表和依赖于x的组件列表。这样就可以方便安装及删除组件。
 1 if(com == "DEPEND")
 2 {
 3     line >> item1;
 4     int id1 = ID(item1), id2;
 5     while(line >> other)
 6     {
 7         id2 = ID(other);
 8         depend[id1].push_back(id2);
 9         be_depended[id2].push_back(id1);
10     }
11 }
为了区别显示安装还是隐式安装,需要一个status[x]数组,0表示组件x未安装,1表示显示安装,2表示隐式安装。
 1 void install(int it, bool toplevel) //toplevel区分显、隐示安装
 2 {
 3     if(!status[it]) //status[x] = 0,组件x未安装
 4     {
 5         for(int i = 0; i < depend[it].size(); i++)
 6         {
 7             install(depend[it][i], false); //所有依赖组件隐式安装,递归调用
 8         }
 9         cout << "   Installing " << name[it] << endl;
10         status[it] = toplevel ? 1 : 2;
11         installed.push_back(it); //把已安装的组件加入到vector数组installed中
12     }
13 }
1 if(com == "INSTALL")
2 {
3     line >> item1;
4     int id = ID(item1);
5     if(status[id]) //若该组件已安装
6         cout << "   " << name[id] << " is already installed." << endl;
7     else
8         install(id, true); //显式安装
9 }
而对于删除组件,首先判断组件能否删除,即是否被未删除的组件依赖,若能删除,在删除后再递归删除他所依赖的组件。
 1 bool needed(int it)
 2 {
 3     for(int i = 0; i < be_depended[it].size(); i++)
 4     {
 5         if(status[be_depended[it][i]]) return true; //组件被未删除组件依赖,
 6     }
 7     return false;
 8 }
 9
10 void Remove(int it, bool toplevel)
11 {
12     if((toplevel || status[it] == 2) && !needed(it))//若该组件显式卸载或它是隐身安装的,且不被依赖,则可以卸载
13     {
14         status[it] = 0;
15         installed.erase( remove(installed.begin(), installed.end(), it), installed.end() ); //注意erase与remove结合的用法
16         cout << "   Removing " << name[it] << endl;
17         for(int i = 0; i < depend[it].size(); i++)
18         {
19             Remove(depend[it][i], false);
20         }
21     }
22 }
剩下的就是小意思了,LIST指令直接按编号输出name[]元素就好;

AC代码如下:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<vector>
  6 #include<string>
  7 #include<map>
  8 #include<set>
  9 #include<algorithm>
 10 #include<cctype>
 11 #include<sstream>
 12 using namespace std;
 13
 14 const int maxn = 10000010;
 15 vector<int> depend[maxn], be_depended[maxn];
 16 vector<int> installed;
 17 map<string, int> item;
 18 string name[maxn];
 19 int status[maxn];
 20 int cnt;
 21 int ID(string It)
 22 {
 23     if(item.count(It)) return item[It];
 24     item[It] = ++cnt;
 25     name[cnt] = It;
 26     return cnt;
 27 }
 28
 29 void install(int it, bool toplevel)
 30 {
 31     if(!status[it]) //status[x] = 0,组件x未安装;status[x] = 1,显示安装;status[x] = 2,隐式安装;
 32     {
 33         for(int i = 0; i < depend[it].size(); i++)
 34         {
 35             install(depend[it][i], false); //隐式安装
 36         }
 37         cout << "   Installing " << name[it] << endl;
 38         status[it] = toplevel ? 1 : 2;
 39         installed.push_back(it);
 40     }
 41 }
 42
 43 bool needed(int it)
 44 {
 45     for(int i = 0; i < be_depended[it].size(); i++)
 46     {
 47         if(status[be_depended[it][i]]) return true; //组件被其他组件依赖,
 48     }
 49     return false;
 50 }
 51
 52 void Remove(int it, bool toplevel)
 53 {
 54     if((toplevel || status[it] == 2) && !needed(it))
 55     {
 56         status[it] = 0;
 57         installed.erase( remove(installed.begin(), installed.end(), it), installed.end() ); ///!!
 58         cout << "   Removing " << name[it] << endl;
 59         for(int i = 0; i < depend[it].size(); i++)
 60         {
 61 //            cout << name[depend[it][i]] << endl;
 62             Remove(depend[it][i], false);
 63         }
 64     }
 65 }
 66
 67 int main()
 68 {
 69     //freopen("in.txt", "r", stdin);
 70     cnt = 0;
 71     string com, item1, other;
 72     getline(cin, com);
 73     while(1)
 74     {
 75         cout << com << endl;
 76         istringstream line(com);
 77         line >> com;
 78         //cout << com << endl;
 79         if(com == "END") break;
 80         if(com == "DEPEND")
 81         {
 82             line >> item1;
 83             int id1 = ID(item1), id2;
 84             while(line >> other)
 85             {
 86                 id2 = ID(other);
 87                 depend[id1].push_back(id2);
 88                 be_depended[id2].push_back(id1);
 89             }
 90         }
 91         else if(com == "INSTALL")
 92         {
 93             line >> item1;
 94             int id = ID(item1);
 95             if(status[id])
 96                 cout << "   " << name[id] << " is already installed." << endl;
 97             else
 98                 install(id, true); //显式安装
 99         }
100         else if(com == "REMOVE")
101         {
102             line >> item1;
103             int id = ID(item1);
104             if(!status[id])
105                 cout << "   " << name[id] << " is not installed." << endl;
106             else if(needed(ID(item1)))
107                 cout << "   " << name[id] << " is still needed." << endl;
108             else
109                 Remove(id, true);  //显式卸载
110         }
111         else if(com == "LIST")
112         {
113             for(int i = 0; i < installed.size(); i++)
114                 cout << "   " << name[installed[i]] << endl;
115         }
116         getline(cin, com);
117     }
118     return 0;
119 }

 
时间: 2024-11-04 07:31:11

【STL+模拟】UVa 506 - System Dependencies的相关文章

UVA 506 System Dependencies(模拟 烂题)

https://vjudge.net/problem/UVA-506 题目是给出了五种指令,DEPEND.INSTALL.REMOVE.LIST.END,操作的格式及功能如下: DEPEND item1 item2 (item3 ...) 安装item1需要先安装item2(.item3--) INSTALL item1 安装item1,如果item1依赖其他组件,则先安装其依赖的其他组件 REMOVE item1 移除item1及其依赖的全部组件,如果组件被其他程序依赖,则不移除 LIST 输

UVa 506 System Dependencies (细节问题)

题意:输入几种指令,让你进行模拟操作,指令如下: DEPEND item1 item2 (item3 ...) 安装item1需要先安装item2(.item3……) INSTALL item1 安装item1,如果item1依赖其他组件,则先安装其依赖的其他组件(如果已经安装就不用安装了) REMOVE item1 移除item1及其依赖的全部组件,如果组件被其他程序依赖,则不移除 LIST 输出当前已安装的所有组件 END 结束程序 析:看到这个题,虽然是放在数据结构这一章里,没觉得有什么数

HDU 4028 The time of a day STL 模拟题

暴力出奇迹.. #include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define ll __int64 #define N 42 ll n,m,ans;

HDU 4022 Bombing STL 模拟题

手动模拟.. #include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define N 10100 #define inf 1000000010 map<

stl+模拟 CCF2016 4 路径解析

1 // stl+模拟 CCF2016 4 路径解析 2 // 一开始题意理解错了.... 3 4 #include <iostream> 5 #include <string> 6 #include <vector> 7 using namespace std; 8 void fre() {freopen("in.txt","r",stdin);} 9 vector<string> l; 10 int main(){

【例题 6-21 UVA - 506】System Dependencies

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 记录每个物品它的依赖有哪些,以及它被哪些东西依赖就可以了. 显式安装的东西不能被隐式删除删掉(就是remove item,然后删除item的依赖的过程叫隐式删除,而删除item本身叫显式删除); 而只能被显式删除. 隐式安装的依赖则可以被显式或隐式删除都行. (显示安装指的是 install item,安装item本身,而安装item的依赖,都称为是隐式的安装) 写个安装和删除的递归函数就好. 样例的答案有误. remove b

Android NDK STL 库调与 System.load

对于Android可使用的STL库有很多,但gnustl功能无疑是最全面. 百度一下,发现很多人对ndk 使用stl库很不全面,往往gunstl static 过分着墨,因此,我这里之讲述 share库的使用. Application.mk Android.mk ndkstl.cpp 预处理一些函数和变量 然后执行代码 int testVector() { vector<string>  catlst; int i = 0; char temp[MAX_BUFFER_SIZE]; for (i

HDU-4961 Boring Sum STL模拟

给出一个序列A,对于A里面的每个元素,左边最近的能被它整除的元素记为B序列对应位置的,右边最近的是它的整数倍的元素记为C序列对应位置,找不到的记它本身,最后算出对应位置B*C的总和. 容器模拟,按顺序扫一遍,每次如果有符合条件的取出来,即为最近的.最后把它的下标放到对应位置的容器中,然后倒序求一遍,最后求和. #include <iostream> #include <cmath> #include <cstdio> #include <cstring> #

HDU-4841 圆桌问题 STL模拟约瑟夫问题

中文题,题意一看就是卧槽,这不约瑟夫么,然后脑子一抽就用了链表写,然后果然T了,最后用Vector模拟的约瑟夫问题. #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <queue> #include <iomanip> #include <algorithm> #include <vector>