week9任务管理器和牌数大小的确定

问题A - 咕咕东的目录管理器

问题描述

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

题目分析

这个题目主要的难点在于设计结构体,如何来表示这个文件以及文件下面的子文件。
在这个地方创建了一个结构体,里面包含了map和vector,int,string,bool多种结构。分别用以记录当前文件的各种信息,文件名,父文件地址,子文件和其对应的编号。
然后再用各个子函数来分开各个操作的处理方式。
建立文件,就是增加当前的map并将最后一个存放有文件信息的下一个 结构体,赋予其新的值,名字和大小,并更新所有的大小。
移动,只需要改变now这个数,将其变化为想要去的文件的地址。
删除文件,就是将now地址里的map删掉即可。
其余的显示结构,则是利用map对应的将其放进对应的vector中,再利用dfs遍历即可。
主要难得是撤回操作,撤回操作对应的上述三个操作都能够进行撤回,所以就要根据这三个专门写一个结构体来储存操作是什么,根目录和操作的目录的地址。但是由于要注意连续撤回的存在,所以不能只存一次的操作,要吧每一次的操作都存下来,于是又加上了一个vector来存放,每次去最后一个操作,将其还原。

代码
#include<iostream>
#include<map>
#include<vector>
#include<iterator> 

#include <string>
using namespace std;

int T,Q;
struct mulu
{
	string name;//名字 
	int pre;//父节点位置 
	map<string,int> child;//子树编号和其名字 
	int size;//大小 
	vector<string> pp,bb;//前5  后5 
	bool pan;//是否更新 
};

mulu menu[200001];
int now,tot; 
struct node//操作的储存 
{
	string name;
	int now;
	int next;
};

vector<node> mm;


void update(int id,int num)	//更新目录大小 
{
	while(id!=-1)

	{
		menu[id].pan=false;
		menu[id].size+=num;
		id=menu[id].pre;
	}
}

void MKDIR(string name)
{
	if(menu[now].child.count(name)==1)
	{
		printf("ERR\n");
		return;
	}
	else
	{
		//menu[now].child.insert(pair<string,int>());
		menu[now].child[name]=tot;
		update(now,1);
		//cout<<"这个文件夹下的大小"<<menu[now].size<<endl;
		menu[tot].name=name;
		menu[tot].pre=now;
		menu[tot].size=1;
		menu[tot].pan=false;
		menu[tot].child.clear();
		menu[tot].pp.clear();
		menu[tot].bb.clear();
		
		//操作放入操作集合中
		node thenode;
		thenode.name="MKDIR";
		thenode.now=now;
		thenode.next=tot;
		mm.push_back(thenode);
		tot++;
		printf("OK\n");
		//cout<<"创建的有 "<<now<<endl;
		//for(map<string,int>::iterator it=menu[now].child.begin();it!=menu[now].child.end();it++)
		//	cout<<it->first<<" "; 
	}
	
	
}

void RM(string name)
{
	if(menu[now].child.count(name)==1)//||menu[wei].child[name]==-1
	{
		int x=menu[now].child[name];
		update(now,-1*menu[x].size);
		menu[now].child.erase(name);
		node thenode;
		thenode.name="RM";
		thenode.now=now;
		thenode.next=x;
		mm.push_back(thenode);
		printf("OK\n");
		return;
	}
	
	else printf("ERR\n");	
}
void CD(string &name)
{
	if(name=="..")
	{
		//cout<<" 尝试      "<<name<<endl;
		if(menu[now].pre==-1)
		{
			printf("ERR\n");
			return;
		}
		node thenode;
		thenode.name="CD";
		thenode.now=now;
		thenode.next=menu[now].pre;
		mm.push_back(thenode);
		now=menu[now].pre;
		printf("OK\n");
		return;
	}
	else
	{
		 if(menu[now].child.count(name)==1)
		{
			node thenode;
			thenode.name="CD";
			thenode.now=now;
			thenode.next=menu[now].child[name];
			mm.push_back(thenode);
			now=menu[now].child[name];
			printf("OK\n");
			return;
		
		}
	
		//cout<<"查询的名字     "<<name<<endl;
		//for(map<string,int>::iterator it=menu[now].child.begin();it!=menu[now].child.end();it++)
		//	cout<<it->first<<" "; 
		printf("ERR\n");
	 }
	
}
void SZ()
{
	printf("%d\n",menu[now].size);
}
void LS()
{
	if(menu[now].child.size()==0)
	{
		
		printf("EMPTY\n");
		return;
	}
	map<string,int>::iterator it;
	if(menu[now].child.size()>=1&&menu[now].child.size()<=10)
	{
		for(it=menu[now].child.begin(); it!=menu[now].child.end(); it++)
			cout<<it->first<<endl;
			//printf("%s\n",it);//加上fisrt无法编译 
			//cout<<it->first<<endl;
			return;
	}
	it=menu[now].child.begin();
	for(int i=1;i<=5;i++)
	{
		cout<<it->first<<endl;
		it++;
	}
	 cout<<"..."<<endl;
	 it=menu[now].child.end();
	 for(int i=1;i<=5;i++)
	 it--;
	 for(int i=1;i<=5;i++)
	 {
	 	cout<<it->first<<endl;
		it++;
	 }
	
}
void quan(int id,vector<string> &pre)
{
	pre.push_back(menu[id].name);
	for(map<string,int>::iterator it=menu[id].child.begin();it!=menu[id].child.end();it++)
		quan(it->second,pre);
}
void pp_track(int id,vector<string>& pre,int num)
{
	pre.push_back(menu[id].name);
	num--;
	if(num==0)
		return;
	for(map<string,int>::iterator it=menu[id].child.begin();it!=menu[id].child.end();it++)
	{
		pp_track(it->second,pre,num);
		if(num==0) break;
	}
}
void bb_track(int id,vector<string>& bck,int num)
{
	map<string,int>::iterator it=menu[id].child.end();
	int n=menu[id].child.size();
	for(int i=0;i<n;i++)
	{
		it--;
		bb_track(it->second,bck,num);
		if(num==0)return;
	}
	bck.push_back(menu[id].name);
	num--;
}
void dfs(int n)
{
	menu[n].bb.clear();
	menu[n].pp.clear();
	if(menu[n].size<=10)
		quan(n,menu[n].pp);
	else
	{
		pp_track(n,menu[n].pp,5);
		bb_track(n,menu[n].bb,5);
	}
	menu[n].pan=true;
} 
void TREE()
{
	map<string,int>::iterator it;
	//cout<<"树结构"<<endl;
	//cout<<menu[now].name<<endl;
	if(!menu[now].pan)//没有遍历过
	 dfs(now);
	 if(menu[now].size==1)
	{
		cout<<"EMPTY"<<endl;
		
	}
	else if(menu[now].size>=1&&menu[now].size<=10)
	{
		for(int i=0;i<menu[now].pp.size();i++)
			cout<<menu[now].pp[i]<<endl;
			//printf("%s\n",it);//加上fisrt无法编译 
			//cout<<it->first<<endl;
			return;
	}
	else
	{
		for(int i=0;i<5;i++)
			cout<<menu[now].pp[i]<<endl;
		cout<<"..."<<endl;
		for(int i=4;i>=0;i--)
			cout<<menu[now].bb[i]<<endl;
	}
}
void UNDO()
{
	if(mm.size()==0)
	{
		printf("ERR\n");
		return ;
	}
	node thenode;
	thenode=mm[mm.size()-1];
	mm.pop_back();
	printf("OK\n");
	//cout<<"上一个操作是:"<<thenode.name<<endl; 
	if(thenode.name=="MKDIR")
	{
		update(thenode.now,-1*menu[thenode.next].size);
		menu[thenode.now].child.erase(menu[thenode.next].name);
	}
	else if(thenode.name=="RM")
	{
		update(thenode.now,menu[thenode.next].size);
		menu[thenode.now].child[menu[thenode.next].name]=thenode.next;
		
	}
	else if(thenode.name=="CD")
	{
		now=thenode.now;
	}
}
int main()
{
	string name;
	string op;
	scanf("%d",&T);
	for(int ti=0;ti<T;ti++)
	{
		scanf("%d",&Q);
		now=0;tot=1;
		menu[0].name="root";
		menu[0].pre=-1;
		menu[0].size=1;
		menu[0].pan=false;
		menu[0].child.clear();
		menu[0].bb.clear();
		menu[0].pp.clear();
		mm.clear();
		for(int qi=0;qi<Q;qi++)
		{
			//scanf("%s",&op);
			cin>>op;
			//cout<<endl<<op<<endl;
			if(op=="MKDIR") 
			{
				cin>>name;
				MKDIR(name);
					
			}
			if(op=="RM")
			{
				cin>>name;
				//scanf("%s",&name);
				RM(name);		
			}
			if(op=="CD")
			{
				cin>>name;
				//scanf("%s",&name);
				CD(name);
			}
			if(op=="SZ")
			{
				SZ();	
				
			}
			if(op=="LS")
			{
				LS();
			}
			if(op=="TREE")
			{
				TREE();
			}
			if(op=="UNDO")
			{
				UNDO();
			}
		
		} 
		
	}
	
	
	
	return 0;
 } 

遇到的问题

主要的问题就是对于stl的不熟悉,比如string和char弄混输入的问题。还有map的具体操作弄混也导致了一定程度的拖延了调试代码的进度

问题B - 东东学打牌

问题描述

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

题目分析

主要需要做的是重载符号小于,方便排序;
建立一个结构体,将需要的信息放进去,玩家的名字,玩家的牌,将牌转化为数字,然后看每个大小的牌有几个,对于mark,tot,和对应的数组(是几个一样的牌,以及那个牌是什么)。
在比较时,先比较mark,它表示目前是哪一种类型的牌,不同类型的牌完全不一样的大小。
如果mrak不一样,那么直接是谁的mark大谁就是大牌。
mark一样的情况下,就挨个比较,两对子的情况就从大往小比较对子的大小,根据具体的mark而定情况。
将char的牌转化为数字,利用了一个tmp数组,然后循环辨认char字符串,‘2’-’9‘分别对应1-9数字,‘A’-1,‘J’-11,‘Q’-12,‘K’-13,‘1’-10;使得对应的tmp[i]++,即确定该牌的个数。
在从后往前遍历tmp数组,看这手牌里有什么样数目的牌,存进结构体中,并对mark进行赋值。
从后往前是为了保证两个对子的时候,第一个一定是这两个中较大的那个对子。

代码
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#include<algorithm>
struct node
{
	char name[12];
	char shu[12];
	int mark;
	int tot;
	int two[3];
	//0,是否有对;1,第一对是什么,2,第二对是什么 
	int three[2];
	int four[2];
	bool shun;
	bool  operator<(const node p)const
	{
		if(mark!=p.mark)
			return mark>p.mark;
		else if(mark==p.mark)
		{
			if(mark==1)
			{
				if(tot!=p.tot)
					return tot>p.tot;
				
			}
			else if(mark==2)
			{
				if(two[1]!=p.two[1])
				{
					return two[1]>p.two[1];
				}
				else if(tot!=p.tot)
				{
					return tot>p.tot;
				}
			}
			else if(mark==3)
			{
				if(two[1]!=p.two[1])
					return two[1]>p.two[1];
				else if(two[2]!=p.two[2])
					return two[2]>p.two[2];
				else if(tot!=p.tot)
					return tot>p.tot;
			}
			else if(mark==4||mark==5)
			{
				if(three[1]!=p.three[1])
					return three[1]>p.three[1];
				else if(tot!=p.tot)
					return tot>p.tot;
			}
			else if(mark==6)
			{
				if(four[1]!=p.four[1])
					return four[1]>p.four[1];
				else if(tot!=p.tot)
					return tot>p.tot;
			}
			else if(mark==7)
			{
				if(tot!=p.tot)
					return tot>p.tot;
			}
		}
		int l1=strlen(name);
		int l2=strlen(p.name);
		for(int j=0;j<min(l1,l2);j++)
		{
			if(name[j]==p.name[j]) continue;
			if(name[j]<p.name[j]) return true;
			if(name[j]>p.name[j] ) return false;
		}
		if(l1<l2) return true;
		else return false;
	}
	
} a[100005];
int tmp[15];
void pre_function(int x)
{
	int i=0;
	memset(tmp,0,sizeof(tmp));
	while(i<strlen(a[x].shu))
	{
		if(a[x].shu[i]=='1')
		{
			tmp[10]++;
			i++;
		}
		else 
		{
			if(a[x].shu[i]>='2'&&a[x].shu[i]<='9')
				tmp[a[x].shu[i]-'0']++;
			else
			{
				if(a[x].shu[i]=='A')
					tmp[1]++;
				if(a[x].shu[i]=='J')
					tmp[11]++;
				if(a[x].shu[i]=='Q')
					tmp[12]++;
				if(a[x].shu[i]=='K')
					tmp[13]++;
			}
		}
		i++;
	}
	if(tmp[1]&&tmp[10]&&tmp[11]&&tmp[12]&&tmp[13])
	{
		a[x].mark=8;
		return;
	}
	for(int i=1;i<=13;i++)
	{
		if(tmp[i])
		{
			for(int j=1;j<=tmp[i];j++)
				a[x].tot+=i;
		}
		
	}
	for(int i=13;i>=1;i--)
	{
		if(tmp[i]==4)
		{
			a[x].four[0]=1;
			a[x].four[1]=i;
			a[x].mark=6;
			return;
		}
		if(tmp[i]==3)
		{
			a[x].three[0]=1;
			a[x].three[1]=i;
		}
		if(tmp[i]==2)
		{
			a[x].two[0]++;
			if(a[x].two[0]==1)
				a[x].two[1]=i;
			else
			{
				a[x].two[2]=i;
				a[x].mark=3;
				return;
			}
		}
	}
	for(int i=1;i<=9;i++)
	if(tmp[i]&&tmp[i+1]&&tmp[i+2]&&tmp[i+3]&&tmp[i+4])
	{
		a[x].shun=1;
		a[x].mark=7;
		return;
	}
	if(a[x].two[0]==1&&a[x].three[0]==1)
	{
		a[x].mark=5;
		return;
	}
	if(a[x].two[0]==1)
	{
		a[x].mark=2;
		return;
	}
	if(a[x].three[0]==1)
	{
		a[x].mark=4;
		return;
	}
	a[x].mark=1;
}
void init(int x)
{
	memset(a[x].two,0,sizeof(a[x].two));
	memset(a[x].three,0,sizeof(a[x].three));
	memset(a[x].four,0,sizeof(a[x].four));
	a[x].shun=0;a[x].mark=0;a[x].tot=0;
 } 
 int main()
 {
 	int n;
 	while(scanf("%d",&n)!=EOF)
 	{
 		//cout<<"n="<<n<<endl;
 		for(int n1=1;n1<=n;n1++)
 		{
 			init(n1);
 			cin>>a[n1].name>>a[n1].shu;
 			pre_function(n1);
 			//scanf("%s",&nodes[n1].name);
 			//getchar();
 			//cout<<nodes[n1].name<<endl;
 			//scanf("%[^\n]",&nodes[n1].shu);
 			//getchar();
 			//cout<<nodes[n1].name<<"    "<<nodes[n1].shu<<endl;
		 }
		 sort(a+1,a+n+1);
		 for(int i=1;i<=n;i++)
		 cout<<a[i].name<<endl;
		 
	 }
 }
遇到的问题

mark值的确定,尤其是3+2和3个的区别

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值