zoukankan      html  css  js  c++  java
  • UVa 506 System Dependencies (细节问题)

    题意:输入几种指令,让你进行模拟操作,指令如下:

    DEPEND item1 item2 (item3 ...) 安装item1需要先安装item2(、item3……)
    INSTALL item1 安装item1,如果item1依赖其他组件,则先安装其依赖的其他组件(如果已经安装就不用安装了)
    REMOVE item1 移除item1及其依赖的全部组件,如果组件被其他程序依赖,则不移除
    LIST 输出当前已安装的所有组件
    END 结束程序

    析:看到这个题,虽然是放在数据结构这一章里,没觉得有什么数据结构的东西,算法上并不难,只是操作麻烦一点,又是调了好长时间,开始用的1024vector,

    RE了,后来我加大了10倍,还有的是后来我看到网上样例不一样都过了,很明显是我没读懂题意,可能移除时顺序是无所谓的。

    首先需要的是把每个名字转化成一个id数,我用了两个map,其实可以不用的,那么时间复杂度可能高一点,然后要两个vector,一个存所依赖的组件,一个存依赖于的组件列表。

    然后还要用一个数组来记录未安装,还是隐式安装,还是显示安装。安装删除时用递归实现较好。

    主要注意以下几点:

      输出比较麻烦,如果已经安装过的显式安装,要输出已经安装了,隐式的直接忽略。

      如果要删除显式安装,除了本身,那么要输出仍然需要。

      如果要删除一个不存在的显式安装,要输出没有安装。

    代码如下:

    #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.
    ";  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.
    ";  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.
    ";//删除显式安装,除了本身,那么要输出仍然需要。
    }
    
    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;
    }
    
  • 相关阅读:
    重新想象 Windows 8 Store Apps (32) 加密解密: 非对称算法, 数据转换的辅助类
    《C#编程极限》目录
    《软件设计精要与模式》完稿(原名《软件设计之道》)
    《软件设计之道》正式更名为《软件设计精要与模式》
    《软件设计精要与模式》各篇之篇首语
    Visual Studio 2005单元测试中关于外部文件的问题解决
    Web Service Software Factory
    Windows下IIS+PHP 5.2的安装与配置
    规划你的C#程序——《C#编程极限》第一章
    《软件设计精要与模式》前言
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5591986.html
Copyright © 2011-2022 走看看