本题参考了一位大哥的代码,可以说是拍案叫绝!
一 题目描述:
二 代码:感觉写的比较清晰了
#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;
}
参考博文: