CSP 202012-3 带配额的文件系统AC

注意点:
1:先判断,再操作
2:可能文件已经存在,先算出需要的文件配额,再创建
3:开 long long

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
//普通文件
struct FNode
{
    ll File_size;
    string name;
    FNode(ll fsize,string name):File_size(fsize),name(name){};
};
//目录
struct LNode
{
    ll File_LD;//目录配额
    ll File_LR;//后代配额
    ll R_File_LD;//已经使用的目录配额
    ll R_File_LR;//已经使用的后代配额
    string name;
    vector<LNode> R_file;//目录下的目录文件
    vector<FNode> D_file;//目录下的普通文件
    LNode(ll size1,ll size2,string name):File_LD(size1),File_LR(size2),name(name)
    {R_File_LD = 0;R_File_LR = 0;}
    LNode(string name)
    {
        File_LD = File_LR = 0;
        this->name = name;
        R_File_LD = 0;
        R_File_LR = 0;
    }
} Root(0,0,"/");



//分割路径

vector<string> split_path(string s)
{
    vector<string> res;
    res.push_back("/");
    string temp_path;
    for(ll i = 1;i<=s.size();++i)
    {
        if(i == s.size() && temp_path.size())
        {
            res.push_back(temp_path);
            break;
        }
        if(s[i] == '/')
        {
            res.push_back(temp_path);
            temp_path.clear();
        }
        else temp_path += s[i];
    }
    return res;
}

//确定要创建文件占用配额的真实大小
ll is_C_size(const vector<string> & path_name,ll file_size)
{
    LNode *temp = &Root;
    ll path_lens = path_name.size();
    for(ll i = 1;i < path_lens; ++ i)
    {
        //最后一个目录
        if(i == path_lens - 1)
        {
            for(ll j = 0;j < temp->D_file.size();++ j)//如果文件已经存在,重新计算需要的配额大小
                if(path_name[i] == temp->D_file[j].name)return file_size - temp->D_file[j].File_size;
        }
        else//前面的目录
        {
            ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
            for(j = 0;j < Rlens;++j)
                if(path_name[i] == (*temp).R_file[j].name)
                {
                    temp = &(temp->R_file[j]);
                    break;
                }
            if(j == Rlens)
                return file_size;
        }
    }
    return file_size;

}

//判断是否能创建
bool is_C(const vector<string> & path_name,ll file_size)
{
    file_size = is_C_size(path_name,file_size);
    LNode *temp = &Root;
    ll path_lens = path_name.size();

    for(ll i = 1;i < path_lens; ++ i)
    {
        if(i == path_lens - 1)
        {
            if(temp->File_LD)//目录配额
                if(temp->R_File_LD + file_size > temp->File_LD)
                    return false;
            if(temp->File_LR)//后代配额
                if(temp->R_File_LR + file_size > temp->File_LR)
                return false;
            for(ll j = 0;j < temp->R_file.size();++ j)//已经存在同名目录
                if(path_name[i] == temp->R_file[j].name)return false;
        }
        else
        {
            ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
            for(j = 0;j < Dlens;++j)//已经存在同名文件
                if(path_name[i] == temp->D_file[j].name)return false;

            if(temp->File_LR)//后代配额
                if(temp->R_File_LR + file_size > temp->File_LR)
                    return false;
            for(j = 0;j < Rlens;++j)
                if(path_name[i] == (*temp).R_file[j].name)//目录存在
                {
                    temp = &(temp->R_file[j]);
                    break;
                }
            if(j == Rlens)//目录不存在
            {
                return true;
            }
        }
    }
    return true;
}


//C
void C_oper()
{
    string path;
    cin>>path;
    ll file_size;
    scanf("%lld",&file_size);
    vector<string> path_name = split_path(path);//解析路径
    if(!is_C(path_name,file_size))
    {
        printf("N\n");
        return ;
    }
    LNode *temp = &Root;
    ll the_file_size = file_size;
    file_size = is_C_size(path_name,file_size);
    ll path_lens = path_name.size();

    for(ll i = 1;i < path_lens; ++ i)
    {
        if(i == path_lens - 1)
        {
            ll j = 0,Dlens = temp->D_file.size();
            //cout<<"the size of D_file is "<<Dlens<<endl;
            for(j = 0;j < Dlens;++ j)
            {
                if(path_name[i] == temp->D_file[j].name)//文件已经存在,直接修改大小
                {
                    //cout << "find " << path_name[i]<< " seccessful!"<<endl;
                    temp->D_file[j].File_size = the_file_size;
                    break;
                }
            }
            if(j == Dlens)//文件不存在,创建
            {
                temp->D_file.push_back(FNode(the_file_size,path_name[i]));
                //cout << "create " << path_name[i]<< " seccessful!"<<endl;
            }
            //修改配额
            temp->R_File_LD += file_size;
            temp->R_File_LR += file_size;
        }
        else
        {
            ll j = 0,Rlens = (*temp).R_file.size();

            temp->R_File_LR += file_size;

            for(j = 0;j < Rlens;++j)
                if(path_name[i] == (*temp).R_file[j].name)//目录存在
                {
                    //cout<<"Find "<<path_name[i]<<endl;
                    temp = &(temp->R_file[j]);
                    break;
                }
            if(j == Rlens)//目录不存在
            {
                //cout<<"Create "<<path_name[i]<<endl;
                temp->R_file.push_back(LNode(path_name[i]));
                temp = &(temp->R_file[j]);
            }
        }
    }
    printf("Y\n");
}


//返回的first为删除的是文件1还是者目录2,或者都不存在0,second为收回的配额大小
pair<ll,ll> is_R_size(const vector<string> & path_name )
{
    LNode *temp = &Root;
    ll path_lens = path_name.size();
    for(ll i = 1;i < path_lens; ++ i)
    {
        if(i == path_lens - 1)
        {
            for(ll j = 0;j < temp->D_file.size();++ j)//删除的是文件
                if(path_name[i] == temp->D_file[j].name)return make_pair(1,temp->D_file[j].File_size);
            for(ll j = 0;j < temp->R_file.size();++ j)//删除的是目录
                if(path_name[i] == temp->R_file[j].name)return make_pair(2, temp->R_file[j].R_File_LR);
        }
        else
        {
            ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
            for(j = 0;j < Rlens;++j)
                if(path_name[i] == (*temp).R_file[j].name)
                {
                    temp = &(temp->R_file[j]);
                    break;
                }
            if(j == Rlens)//上级目录不存在
                return make_pair(0,-1);
        }
    }
    return make_pair(0,-1);
}

//R
void R_oper()
{
    string path;
    cin>>path;
    vector<string> path_name = split_path(path);
    auto R_size = is_R_size(path_name);
    printf("Y\n");
    if(R_size.first == 0)
        return ;
    LNode *temp = &Root;
    ll path_lens = path_name.size();
    ll file_type = R_size.first,file_size = R_size.second;
    for(ll i = 1;i < path_lens; ++ i)
    {
        if(i == path_lens - 1)
        {

            temp->R_File_LR -= file_size;//收回后代配额
            if(file_type == 1)
            {
                ll j = 0;
                for(j = 0;j < temp->D_file.size();++ j)
                    if(path_name[i] == temp->D_file[j].name)
                        break;
                temp->D_file.erase(temp->D_file.begin() + j);//删除文件

                temp->R_File_LD -= file_size;//收回目录配额
            }
            else
            {
                ll j = 0;
                for(j = 0;j < temp->R_file.size();++ j)
                    if(path_name[i] == temp->R_file[j].name)
                        break;
                temp->R_file.erase(temp->R_file.begin() + j);//删除目录
            }

        }
        else
        {
            ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();

            temp->R_File_LR -= file_size;
            for(j = 0;j < Rlens;++j)
                if(path_name[i] == (*temp).R_file[j].name)
                {
                    temp = &(temp->R_file[j]);
                    break;
                }
        }
    }
}



//是否能够更新配额
bool is_Q_size(const vector<string> & path_name,ll file_lr,ll file_ld)
{
    LNode *temp = &Root;
    ll path_lens = path_name.size();
    //更新/目录
    if(path_lens == 1)
    {
        if(!file_lr && !file_ld)
            return true;
        if(!file_lr)
        {
            if(file_ld >= temp->R_File_LD)return true;
            else return false;
        }
        if(!file_ld)
        {
            if(file_lr >= temp->R_File_LR)return true;
            else return false;
        }
        if(file_lr >= temp->R_File_LR && file_ld >= temp->R_File_LD)
            return true;
        else return false;
    }
    //更新/目录下的目录
    for(ll i = 1;i < path_lens; ++ i)
    {

        ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
        for(j = 0;j < Rlens;++j)
            if(path_name[i] == (*temp).R_file[j].name)
            {
                temp = &(temp->R_file[j]);
                break;
            }
        if(j == Rlens)//目录不存在
            return false;

        if(i == path_lens - 1)
        {
            //判断是否满足配额
            if(!file_lr && !file_ld)
                return true;
            if(!file_lr)
            {
                if(file_ld >= temp->R_File_LD)return true;
                else return false;
            }
            if(!file_ld)
            {
                if(file_lr >= temp->R_File_LR)return true;
                else return false;
            }
            if(file_lr >= temp->R_File_LR && file_ld >= temp->R_File_LD)
                return true;
            else return false;
        }

    }
    return false;

}


//Q
void Q_oper()
{
    string path;
    cin>>path;
    ll file_rd,file_ld;
    scanf("%lld%lld",&file_ld,&file_rd);
    vector<string> path_name = split_path(path);
    if(!is_Q_size(path_name,file_rd,file_ld))
    {
        printf("N\n");
        return ;
    }
    LNode *temp = &Root;
    ll path_lens = path_name.size();

    if(path_lens == 1)//修改/目录配额
    {
        temp->File_LR = file_rd;
        temp->File_LD = file_ld;
    }
    for(ll i = 1;i < path_lens; ++ i)
    {

        ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
        for(j = 0;j < Rlens;++j)
            if(path_name[i] == (*temp).R_file[j].name)
            {
                temp = &(temp->R_file[j]);
                break;
            }

        if(i == path_lens - 1)//修改配额
        {
            temp->File_LR = file_rd;
            temp->File_LD = file_ld;
        }


    }
    printf("Y\n");
}


//打印所有文件
void output(LNode * root)
{
    ll Rlens = root->R_file.size(),Dlens = root->D_file.size();
    cout<<root->name<<"\n";
    cout<<"----------"<<root->name<<" LD: "<<root->File_LD<<" "<<root->R_File_LD<<"-----------\n";
    for(ll i = 0;i < Dlens;++ i)
        cout<<root->D_file[i].name<<":"<<root->D_file[i].File_size<<" ";
    cout<<endl;
    cout<<"----------"<<root->name<<" LR "<<root->File_LR<<" "<<root->R_File_LR<<"-----------\n";
    for(ll i = 0;i < Rlens;++i)
    {
        output(&(root->R_file[i]));
    }

}

int main()
{
    ll t;
    scanf("%lld",&t);
    //output(&Root);
    while(t -- )
    {

        string oper;
        cin>>oper;
        if(oper[0] == 'C')
            C_oper();
        else if(oper[0] == 'R')
            R_oper();
        else if(oper[0] == 'Q')
            Q_oper();
        //output(&Root);
    }

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值