【CCF刷题】202012-3-带配额的文件系统(C++70分)

记录一下而已,不要看

#include <bits/stdc++.h>

using namespace std;

#define DIR_T 0
#define FILE_T 1
#define ANY 2

struct Node{
public:
    string name;            // 名字
    int type;               // 0-directory,1-file
    long long siz;               // 文件大小,对于目录,它是0
    map<string, Node*> children; // 孩子 <名字, 节点>
    long long ld;                // 孩子配额
    long long lr;                // 后代配额
    long long curD;              // 当前孩子大小
    long long curR;              // 当前后代大小
    typedef map<string, Node*>::iterator Iter;  // 迭代器
    Node(string name, int type, long long siz){
        this->name = name;
        this->type = type;
        if(type == FILE_T){
            this->siz = siz;
        } else{
            this->siz = 0;
        }
        ld = lr = curD = curR = 0;
    }
public:
    bool create(const string& pathStr, const long long siz){
        int endPos = pathStr.find("/");
        string name = pathStr.substr(0, endPos);
        if(endPos == string::npos){ // 递归最底层,文件是该目录的孩子
            return createFile(name, siz);
        }
        if(lr != 0 && curR + siz > lr){ // 超过后代配额
            return false;
        }
        Node* child = getChildByName(name);
        Node* newNode = NULL;
        bool success = false;
        if(child != NULL){ // 有同名的孩子
            if(child->type == DIR_T){ // 且为目录
                success = child->create(pathStr.substr(endPos + 1), siz);
            }
        } else{ // 没有同名孩子,则创建
            newNode = new Node(name, DIR_T, 0);
            success = newNode->create(pathStr.substr(endPos + 1), siz);
        }
        if(success){
            postCreate(newNode, name, siz);
        }
        return success;
    }

    long long remove(const string& pathStr, int type){
        int endPos = pathStr.find("/");
        string name = pathStr.substr(0, endPos);
        Node* child = getChildByName(name);
        if(child == NULL){
            return 0;
        }
        if(endPos == string::npos){
            long long siz = 0;
            if(child->type == FILE_T) {
                siz = child->siz;
                this->children.erase(name);
                this->curD -= siz;
                this->curR -= siz;
            } else if(type == ANY){
                siz = child->curR;
                this->children.erase(name);
                this->curR -= siz;
            }
            return siz;
        }
        long long siz = child->remove(pathStr.substr(endPos + 1), type);
        this->curR -= siz;
        return siz;
    }

    bool quota(const string& pathStr, long long newD, long long newR){
        int endPos = pathStr.find("/");
        string name = pathStr.substr(0, endPos);
        Node* child = getChildByName(name);
        if(child == NULL){
            return false;
        }
        if(endPos == string::npos){
            if(child->type == DIR_T
               &&(newD == 0 || newD != 0 && newD >= child->curD)
               &&(newR == 0 || newR != 0 && newR >= child->curR)){
                child->ld = newD;
                child->lr = newR;
                return true;
            }
            return false;
        }
        return child->quota(pathStr.substr(endPos + 1), newD, newR);
    }
private:

    // 递归的最底层创建文件
    bool createFile(const string& filename, const long long siz){
        if(ld != 0 && curD + siz > ld
           || lr != 0 && curR + siz > lr){
            return false;
        }
        Node* child = getChildByName(filename);
        if(child != NULL && child->type == DIR_T){
            return false;
        }
        this->curD += siz;
        this->curR += siz;
        Node* fileNode = new Node(filename, FILE_T, siz);
        this->children[filename] = fileNode;
        return true;
    }


    // 创建完后更新curR,以及添加孩子
    void postCreate(Node* newNode, string name, long long siz){
        if(newNode != NULL){
            this->children[name] = newNode;
        }
        this->curR += siz;
    }

    // 如果用children[name]来查找孩子且孩子不存在的话,
    // 会导致创建children[name] = NULL,所以要用find来找
    Node* getChildByName(const string& name){
        Iter it = this->children.find(name);
        if(it == this->children.end()){
            return NULL;
        }
        return it->second;
    }
//public:
//    void print(){
//        printInternal("");
//        cout<<endl;
//    }
//private:
//    void printInternal(string indent){
//        cout<< indent << "|--" << name << " size: " << siz
//         << " curD: " << curD << " curR: " << curR <<endl;
//        for(auto i:children){
//            if(i.second->getChildByName("") == NULL){
//                i.second->printInternal(indent+"  ");
//            }
//        }
//    }
};


int main(){
    Node* root = new Node("Root", DIR_T, 0);
    root->children[""] = root; // 为了方便修改配额,循环定义根的孩子是自己
    int n;
    char cmd;
    string path;
    long long val1, val2;
    cin>>n;
    for(int i=0;i<n;++i){
        cin>>cmd;
        switch(cmd){
            case 'C':
                cin>>path>>val1;
                root->remove(path.substr(1), FILE_T);
                if(root->create(path.substr(1), val1)){
                    cout<<"Y\n";
                }else{
                    cout<<"N\n";
                }
            break;
            case 'R':
                cin>>path;
                root->remove(path.substr(1), ANY);
                cout<<"Y\n";
            break;
            case 'Q':
                cin>>path>>val1>>val2;
                if(root->quota(path.substr(1), val1, val2)){
                    cout<<"Y\n";
                }else{
                    cout<<"N\n";
                }
            break;
        }
//        root->print();
    }

    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值