目录
题意:输入几种指令,让你进行模拟操作,指令如下:
DEPEND item1 item2 (item3 ...) | 安装item1需要先安装item2(、item3……) |
INSTALL item1 | 安装item1,如果item1依赖其他组件,则先安装其依赖的其他组件(如果已经安装就不用安装了) |
REMOVE item1 | 移除item1及其依赖的全部组件,如果组件被其他程序依赖,则不移除 |
LIST | 输出当前已安装的所有组件 |
END | 结束程序 |
析:看到这个题,虽然是放在数据结构这一章里,没觉得有什么数据结构的东西,算法上并不难,只是操作麻烦一点,又是调了好长时间,开始用的1024vector,
RE了,后来我加大了10倍,还有的是后来我看到网上样例不一样都过了,很明显是我没读懂题意,可能移除时顺序是无所谓的。
首先需要的是把每个名字转化成一个id数,我用了两个map,其实可以不用的,那么时间复杂度可能高一点,然后要两个vector,一个存所依赖的组件,一个存依赖于的组件列表。
然后还要用一个数组来记录未安装,还是隐式安装,还是显示安装。安装删除时用递归实现较好。
主要注意以下几点:
输出比较麻烦,如果已经安装过的显式安装,要输出已经安装了,隐式的直接忽略。
如果要删除显式安装,除了本身,那么要输出仍然需要。
如果要删除一个不存在的显式安装,要输出没有安装。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <sstream> #include <map> #include <algorithm> using namespace std; const int maxn = 10240; vector< int > v1[maxn]; vector< int > v2[maxn]; vector< int > is_install; map<string, int > mp; map< int , string> item; int cnt = 0; int status[maxn]; //0表示未安装,1表示隐式安装,2表示显式安装 int getid( const string &s){ //获得id if (mp.count(s)) return mp[s]; mp[s] = ++cnt; item[cnt] = s; return cnt; } void install( int t, bool ok){ if (status[t] && ok){ cout << " " << item[t] << " is already installed.\n" ; return ; } //已经安装过的显式安装,要输出已经安装了 if (status[t]) return ; //隐式安装,忽略 for ( int i = 0; i < v1[t].size(); ++i) install(v1[t][i], false ); //递归查找安装 cout << " Installing " << item[t] << endl; status[t] = ok ? 1 : 2; //确定是隐式安装还是显式安装 is_install.push_back(t); } bool need( int t){ for ( int i = 0; i < v2[t].size(); ++i) if (status[v2[t][i]]) return true ; //这个地方我刚开始写的是 2 == status[v2[t][i]], //结果不对,因为首先在存储时就已经确定了,存入的都是显式安装的,并不用重新判定, //只要判定是不是移除了就好,另外的是在安装时实验它的状态可能会改变,所以不能这么写 return false ; } void remove1( int t, bool ok){ if (ok && !status[t]){ cout << " " << item[t] << " is not installed.\n" ; return ; } //删除一个不存在的显式安装,要输出没有安装。 if ((ok || status[t] == 2) && !need(t)){ status[t] = 0; is_install.erase( remove (is_install.begin(), is_install.end(), t), is_install.end()); //remove不是真删除元素,而是把它们放到后面去,并返回地扯 cout << " Removing " << item[t] << endl; for ( int i = v1[t].size()-1; i >= 0; --i) //这个地方如果从0开始也对,应该是我没读懂题意吧 remove1(v1[t][i], false ); return ; } if (ok) cout << " " << item[t] << " is still needed.\n" ; //删除显式安装,除了本身,那么要输出仍然需要。 } int main(){ // freopen("in.txt", "r", stdin); string s; memset (status, 0, sizeof (status)); while (getline(cin, s)){ cout << s << endl; if (s == "END" ) break ; stringstream ss(s); string s1, s2; ss >> s1; if ( 'D' == s1[0]){ ss >> s2; int t = getid(s2); while (ss >> s){ v1[t].push_back(getid(s)); v2[getid(s)].push_back(t); } } else if ( 'I' == s1[0]){ while (ss >> s2) install(getid(s2), true ); } else if ( 'R' == s1[0]){ ss >> s2; remove1(getid(s2), true ); } else if ( 'L' == s1[0]){ for ( int i = 0; i < is_install.size(); ++i) cout << " " << item[is_install[i]] << endl; } } return 0; } |
分类:
数据结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)