CCF 202012-3 带配额的文件系统 大模拟 100分

本题参考了一位大哥的代码,可以说是拍案叫绝!

一 题目描述:

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

二 代码:感觉写的比较清晰了

#include <iostream>
#include <map>
#include <string>
#include <algorithm>
#include <sstream>
#include <vector>
#include <limits.h>
using namespace std;
const int maxn = 4e6+5;
typedef long long int ll;
struct Node{
    map<string,int> child;//孩子的名字+孩子的下标
    ll max_ld1,max_ld2;//max_ld1:目录配额,max_ld2:后代配额
    ll ld1,ld2;//max_ld1:现有的目录配额,max_ld2:现有的后代配额
    ll fsize;//文件大小
    int flag;//1为文件,2为目录
    int fa_id;//父亲的下标
};
Node node[maxn];//数据结构:静态树
int n,index = 0;

vector< pair<int,string> > reback;
void Reback()//妙妙妙
{
    int i;
    for(i=0;i<(int)reback.size();i++)
    {
        int f_id = reback[i].first;
        string son_name = reback[i].second;
        node[f_id].child.erase(son_name);
    }
}
string Cdo()
{
    //第一步:两个输入,找出最后的/
    string path;ll fsize;
    cin>>path>>fsize;
    int last = path.rfind("/");
/***********************/
    int p =1;
    int id = 0;
    int tindex = index;
    reback.clear();
    while(p<last)
    {
        string t="";
        for(;p < last&&path[p] != '/';p++)
        {
            t+=path[p];
        }
        p++;
        if(node[id].child.find(t) == node[id].child.end())
        {
            node[id].child[t] = ++index;
            node[index].fa_id = id;
            node[index].flag = 2;
            node[index].max_ld1 = LLONG_MAX/3;
            node[index].max_ld2 = LLONG_MAX/3;
            reback.push_back(make_pair(id,t));
            id = index;
        }else{
            int sonid = node[id].child[t];
            if(node[sonid].flag == 1) {index = tindex;Reback();return "N";}
            id = sonid;
        }
    }
/*******到此目录部分已处理********/
    string f_name = path.substr(last+1);//取出要创建的文件名
    if(node[id].child.find(f_name) != node[id].child.end())
    {
        int sonid = node[id].child[f_name];
        if(node[sonid].flag == 2){index = tindex;Reback();return "N";}
    }
/***********到此,“若路径所指文件已经存在,但是目录文件的,则该指令不能执行成功”处理完毕**********/
    ll py;//记录增加的文件大小,验证假设创建之后的配额情况
    if(node[id].child.find(f_name) == node[id].child.end())
        py = fsize;
    else if(node[id].child.find(f_name) != node[id].child.end())
        py = fsize - node[node[id].child[f_name]].fsize;
    if(node[id].ld1 + py > node[id].max_ld1) {index = tindex;Reback();return "N";}//验证父亲的目录配额
    int temp_id = id;
    while(temp_id != -1)//验证祖先的后代配额
    {
        if(node[temp_id].ld2 + py > node[temp_id].max_ld2) {index = tindex;Reback();return "N";}
        temp_id = node[temp_id].fa_id;
    }
/*********到此配额已经检查完毕*************/
    if(node[id].child.find(f_name) == node[id].child.end())//要么创建
    {
        node[id].child[f_name] = ++index;
        node[index].fa_id = id;
        node[index].flag = 1;
        node[index].fsize = fsize;
    }else if(node[id].child.find(f_name) != node[id].child.end())//要么替换,修改大小即可
    {
        int sonid = node[id].child[f_name];
        node[sonid].fsize = fsize;
    }
    node[id].ld1 += py;//修改父亲的现有的目录配额
    int temp_id2 = id;
    while(temp_id2 != -1)//修改祖先的现有的后代配额
    {
        node[temp_id2].ld2 += py;
        temp_id2 = node[temp_id2].fa_id;
    }
    return "Y";
}

string Rdo()
{
    string path;
    cin>>path;
    int last = path.rfind('/');
/**********************************/
    int p = 1;
    int id = 0;
    while(p<last)
    {
        string t="";
        for(;p < last&&path[p] != '/';p++)
        {
            t+=path[p];
        }
        p++;
        if(node[id].child.find(t) == node[id].child.end()){return "Y";}
        else{
            int sonid = node[id].child[t];
            if(node[sonid].flag == 1) {return "Y";}
            id = sonid;
        }
    }
/*************目录处理完毕*****************/
    string f_name = path.substr(last+1);
    if(node[id].child.find(f_name) == node[id].child.end())
        return "Y";
    if(node[id].child.find(f_name) != node[id].child.end())
    {
        int sonid = node[id].child[f_name];
        if(node[sonid].flag == 1) //如果是文件
        {
            node[id].child.erase(f_name);
            node[id].ld1 -= node[sonid].fsize;//修改父亲的现有的目录配额
            int temp_id = id;
            while(temp_id != -1)//修改祖先的现有的后代配额
            {
                node[temp_id].ld2 -= node[sonid].fsize;
                temp_id = node[temp_id].fa_id;
            }
        }else if(node[sonid].flag == 2)//如果是目录
        {
            node[id].child.erase(f_name);
            int temp_id = id;
            while(temp_id != -1)//修改祖先的现有的后代配额
            {
                node[temp_id].ld2 -= node[sonid].ld2;
                temp_id = node[temp_id].fa_id;
            }
        }
    }
    return "Y";
}

string Qdo()
{
    string path;
    ll set_ld1,set_ld2;
    cin>>path>>set_ld1>>set_ld2;
    if(set_ld1==0) set_ld1=LLONG_MAX/3;
    if(set_ld2==0) set_ld2=LLONG_MAX/3;
    int last = path.rfind('/');
/**********************************/
    int p = 1;
    int id = 0;
    while(p<last)
    {
        string t="";
        for(;p<last&&path[p] != '/';p++)
        {
            t+=path[p];
        }
        p++;
        if(node[id].child.find(t) == node[id].child.end()){return "N";}
        else{
            int sonid = node[id].child[t];
            if(node[sonid].flag == 1) {return "N";}
            id = sonid;
        }
    }
/***************************************/
    string f_name = path.substr(last+1);
    int qnode;//代表要修改配额的目录
    if(f_name.size() == 0)//是根目录
        qnode = 0;
    else{
        if(node[id].child.find(f_name) == node[id].child.end()) return "N";//没有这个目录
        else qnode = node[id].child[f_name];
    }
    if(node[qnode].flag == 1) return "N";//是文件
    else{
        if(set_ld1<node[qnode].ld1||set_ld2<node[qnode].ld2) return "N";//检查配额
        else{
            node[qnode].max_ld1 = set_ld1;
            node[qnode].max_ld2 = set_ld2;
            return "Y";
        }
    }
}
int main()
{
    node[0].fa_id = -1;node[0].flag = 2;node[0].max_ld1 = LLONG_MAX/3;node[0].max_ld2 = LLONG_MAX/3;
    int i;
    string str;
    char c;
    cin>>n;
    for(i=0;i<n;i++)
    {
        cin>>c;
        if(c == 'C')
        {
            cout<<Cdo()<<'\n';
        }
        if(c == 'R')
        {
            cout<<Rdo()<<'\n';
        }
        if(c == 'Q')
        {
            cout<<Qdo()<<'\n';
        }
    }
    return 0;
}


参考博文:

大哥的文章

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页