目录管理器2016-ACM(week9hw)

A - 咕咕东的目录管理器

题目

咕咕东的雪梨电脑的操作系统在上个月受到宇宙射线的影响,时不时发生故障,他受不了了,想要写一个高效易用零bug的操作系统 —— 这工程量太大了,所以他定了一个小目标,从实现一个目录管理器开始。前些日子,东东的电脑终于因为过度收到宇宙射线的影响而宕机,无法写代码。他的好友TT正忙着在B站看猫片,另一位好友瑞神正忙着打守望先锋。现在只有你能帮助东东!

初始时,咕咕东的硬盘是空的,命令行的当前目录为根目录 root。

目录管理器可以理解为要维护一棵有根树结构,每个目录的儿子必须保持字典序。

现在咕咕东可以在命令行下执行以下表格中描述的命令:在这里插入图片描述输入
输入文件包含多组测试数据,第一行输入一个整数表示测试数据的组数 T (T <= 20);

每组测试数据的第一行输入一个整数表示该组测试数据的命令总数 Q (Q <= 1e5);

每组测试数据的 2 ~ Q+1 行为具体的操作 (MKDIR、RM 操作总数不超过 5000);
面对数据范围你要思考的是他们代表的 “命令” 执行的最大可接受复杂度,只有这样你才能知道你需要设计的是怎样复杂度的系统。

output
每组测试数据的输出结果间需要输出一行空行。注意大小写敏感。
限制
Time limit 6000 ms

Memory limit 1048576 kB
样例

1
22
MKDIR dira
CD dirb
CD dira
MKDIR a
MKDIR b
MKDIR c
CD ..
MKDIR dirb
CD dirb
MKDIR x
CD ..
MKDIR dirc
CD dirc
MKDIR y
CD ..
SZ
LS
TREE
RM dira
TREE
UNDO
TREE
OK
ERR
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
9
dira
dirb
dirc
root
dira
a
b
c
dirb
x
dirc
y
OK
root
dirb
x
dirc
y
OK
root
dira
a
b
c
dirb
x
dirc
y

代码

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<map>
#include<string>
#include<string.h>
#include<vector>
using namespace std;

char tmps[50];//string类型不能scanf 
struct directory
{
	string name;
	map<string,directory*> children;//以便通过子目录名字取到子目录
	int subTreeSize;
	directory* parent;
	
	vector<string> tenDescen;//保存当前节点的是个后代
	bool updated;//是否已更新树 
	
	directory(string _name,directory* _parent)
	{
		name=_name;
		parent=_parent;
		subTreeSize=1;
	}
	
public:
	directory* mkdir(string name); 
	void maintain(int x);//向上维护子树大小 
	directory* rm(string name);
	directory* cd(string name);
	directory* getChild(string name);
	void sz();
	void ls();
	void tree();
	bool addChild(directory* d);
private:
	void treeAll(vector<string> *v);//将后代全部加入数组中 
	void treeFirstFive(int n,vector<string> *v);//将后代的前五个加入数组中
	void treeLastFive(int n,vector<string> *v);//将后代后五个加入数组中 

};
struct command
{
	const string commands[7]={"MKDIR","RM","CD","SZ","LS","TREE","UNDO"};
	int type;//类型
	string arg;//参数 
	directory* tmpDir;//记录各操作返回值 
	
	command(string s)
	{
		for(int i=0;i<7;i++)
			if(s==commands[i])
			{
				type=i;
				if(i<3)
				{
					scanf("%s",&tmps);
					arg=tmps;
					
				}
				return ;
			} 
	}
};

void solve()
{
	int q,co;
	scanf("%d",&q);
	directory* now=new directory("root",NULL);
	vector<command*> allCmd;//保存成功执行的操作,以便undo 
	while(q--)
	{
		scanf("%s",&tmps);
		command* cmd=new command(tmps);
		switch(cmd->type)
		{
			case 0://MADIR
				{
					cmd->tmpDir=now->mkdir(cmd->arg);
					if(cmd->tmpDir==NULL)printf("ERR\n");
					else
					{
						printf("OK\n");
						allCmd.push_back(cmd);
					}
				}
				break;
			case 1://RM
				{
					cmd->tmpDir=now->rm(cmd->arg);
					if(cmd->tmpDir==NULL)printf("ERR\n");
					else
					{
						printf("OK\n");
						allCmd.push_back(cmd);
					}
				}
				break;
			case 2://CD
				{
					directory* ch=now->cd(cmd->arg);
					if(ch==NULL)printf("ERR\n");
					else
					{
						printf("OK\n");
						cmd->tmpDir=now;//保留原有目录 
						now=ch;
						allCmd.push_back(cmd);
					}
				}
				break;
			case 3://SZ
				now->sz();break;
			case 4://LS
				now->ls();break;
			case 5://TREE
				now->tree();break;
			case 6://UNDO,撤销上一个成功执行的操作,操作仅限mkdir\rm\cd 
				{
					bool success=false;
					while(!success&&!allCmd.empty())
					{
						cmd=allCmd.back();allCmd.pop_back();
						switch(cmd->type)
						{
							case 0:
								{
									directory* t=now->rm(cmd->arg);
									if(t!=NULL)success=true;
								} 
								break;
							case 1:
								{
									success=now->addChild(cmd->tmpDir);
									
								}
								break;
							case 2:
								{
									now=cmd->tmpDir;
									success=true;
								}
								break;
						}
					}
					if(success)printf("OK\n");
					else printf("ERR\n");
				}
				break;
			
		}
	}
}

directory* directory::mkdir(string name)
{
	//成功返回子目录,否则返回空
	if(children.find(name)!=children.end())
		return NULL;
	directory* sub=new directory(name,this);
	children[name]=sub;
	maintain(1);
	return sub;
	
}
directory* directory::rm(string name)
{
	if(children.find(name)==children.end())
		return NULL;
	std::map<string,directory*>::iterator it=children.find(name);
	maintain(-1*it->second->subTreeSize);
	children.erase(it);
	return it->second;
}

directory* directory::cd(string name)
{
	if(name=="..")
		return this->parent;
	return getChild(name);
	
}
directory* directory::getChild(string name)
{
	std::map<string,directory*>::iterator it=children.find(name);
	if(it==children.end())return NULL;
	return it->second;
}

void directory::ls()
{
	int s=children.size();
	if(s==0)printf("EMPTY\n");
	else if(s<=10)
		for(std::map<string,directory*>::iterator it=children.begin();it!=children.end();it++)
			printf("%s\n",it->first.c_str());
	else
	{
		std::map<string,directory*>::iterator it=children.begin();
		for(int i=0;i<5;i++,it++)
			printf("%s\n",it->first.c_str());
		printf("...\n");
		it=children.end();
		for(int i=0;i<5;i++,it--);
		for(int i=0;i<5;i++,it++)
			printf("%s\n",it->first.c_str());
		
	}
}

void directory::sz()
{
	printf("%d\n",this->subTreeSize);
}
void directory::maintain(int x)
{
	updated=true;
	subTreeSize+=x;
	if(parent!=NULL)
		parent->maintain(x);
}

bool directory::addChild(directory* d)
{
	if(children.find(d->name)!=children.end())
		return false;
	children[d->name]=d;
	maintain(d->subTreeSize);
	return true;
}

void directory::tree()
{
	//缓存(懒更新)
	if(subTreeSize==1)printf("EMPTY\n");
	else if(subTreeSize<=10)
	{
		if(updated)//已更新
		{
			tenDescen.clear();
			
			treeAll(&tenDescen);//将后代全部加入数组
			updated=false;
			 
		}
		for(int i=0;i<subTreeSize;i++)
			printf("%s\n",tenDescen.at(i).c_str()); 
	}
	else 
	{
		if(updated)
		{
			tenDescen.clear();
			treeFirstFive(5,&tenDescen);
			treeLastFive(5,&tenDescen);
			updated=false;
		}
		for(int i=0;i<5;i++)
			printf("%s\n",tenDescen.at(i).c_str());
		printf("...\n");
		for(int i=9;i>=5;i--)
			printf("%s\n",tenDescen.at(i).c_str()); 
	}
	 
}
void directory::treeAll(vector<string>* v)
{
	v->push_back(name);
	
	
	for(std::map<string,directory*>::iterator it=children.begin();it!=children.end();it++)
		it->second->treeAll(v);
}

void directory::treeFirstFive(int n,vector<string>* v)
{
	v->push_back(name);
	if(--n==0)return;
	int s=children.size();
	std::map<string,directory*>::iterator it=children.begin();
	while(s--)
	{
		int st=it->second->subTreeSize;
		if(st>=n)
		{
			it->second->treeFirstFive(n,v);
			return;
		}
		else
		{
			
			it->second->treeFirstFive(st,v);
			n-=st;
		}
		it++;
	}
} 


void directory::treeLastFive(int n,vector<string>* v)
{
	
	int s=children.size();
	std::map<string,directory*>::iterator it=children.end();
	while(s--)
	{
		it--;
		int st=it->second->subTreeSize;
		if(st>=n)
		{
			it->second->treeLastFive(n,v);
			return;
		}
		else
		{
			
			it->second->treeLastFive(st,v);
			
			n-=st;
		}
		
	}
	v->push_back(name);
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
		solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值