记录week9的实验一道题+作业三道题

咕咕东的目录管理器、东东学打牌 、签到题、炉石传说

作业:

咕咕东的目录管理器:
原题链接
题意大概就是模拟一个类似linux的目录管理器,并且模拟题目里所给出的操作。这是一道复杂的模拟题,整道题很难找到头绪,经过课上的讲解,我们运用面向对象的思路去解题。
构建命令结构和目录结构,用树的方式描述目录,以map存储孩子。
题目的难点主要在tree操作,在这一步需要对树进行输出,由于题目的数据范围很大,要判断是否已经访问过了,进行记忆化操作。同时要注意迭代器在删除插入后会失效。
整道题目即使是做完了页感觉很难把握脉络,他是由很多子模块合成的一道题,在写的时候,常常会出现突然又需要新的功能,这时候在之前写好的地方又要加入新的元素,这些变数是很难开始的时候就能想到的,比起算法题更像是一道数据结构实验。需要你边写边去更改。

#include<iostream>
#include<map>
#include<string>
#include<vector>
using namespace std;

const string c[7] = {"MKDIR","RM","CD","SZ","LS","TREE","UNDO" };
string temp;
struct Direct {
	string name;
	map<string, Direct*>children;
	Direct* parent;
	int tsize;
	bool update;
	vector<string> ten;
	Direct(string na, Direct* p)
	{
		this->name = na;
		this->parent = p;
		this->tsize = 1;

	}

public:
	bool addchild(Direct* ch)
	{
		if (children.find(ch->name) !=  children.end())
		{
			 return false;
		}
		else
		{
			children[ch->name] = ch;
			maintain(+ch->tsize);
			return true;
		}
	}
	Direct* getchild(string s)
	{
		auto it = children.find(s);
		if (it == children.end())return NULL;
		else return it->second;
	}
	void maintain(int d)
	{
		update = true;
		tsize = tsize + d;
		if (parent != NULL)
		{
			parent->maintain(d);
		}
	}
public:

	Direct* mkdir(string name)
	{
		if (children.find(name) != children.end())
			return NULL;
		else
		{
			Direct* ch = new Direct(name, this);
			children[name] = ch;
			maintain(+1);
			return ch;
		}
	}
	Direct* rm(string name)
	{
		auto it = children.find(name);
		if (it == children.end())
			return NULL;
		else
		{
			Direct* iter = it->second;
			maintain(-1 * it->second->tsize);
			it = children.erase(it);
			return iter;
		}
	}
	Direct* cd(string name)
	{
		if (name == "..")
		{
			return this->parent;
		}
		else
		{
			return getchild(name);
		}
	}
	void sz()
	{
		printf("%d\n", this->tsize);
	}
	void ls()
	{
		int sz = children.size();
		if (sz == 0)printf("EMPTY\n");
		else if (sz <= 10)for (auto& entry : children)printf("%s\n", entry.first.c_str());
		else
		{
			auto 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());
		}
	}
	//root
	//dira
	//a
	//b
	//c
	//dirb
	//x
	//dirc
	//y
	void tree()
	{
		if (tsize == 1)printf("EMPTY\n");
		else if (tsize <= 10)
		{
			if (this->update)
			{
				ten.clear();
				treeall(&ten); //cout<<"dddddddd"<<endl;	
				this->update = false;
			}//cout<<ten.size()<<endl;
			for (int i = 0; i <ten.size(); i++)printf("%s\n", ten.at(i).c_str());
		}
		else {
			if (this->update)
			{
				ten.clear();
				treefirst(5, &ten);
				treelast(5, &ten);
				this->update = false;
			}
			for (int i = 0; i < 5; i++)printf("%s\n", ten.at(i).c_str());
			printf("...\n");
			for (int i = 9; i >= 5; i--)printf("%s\n", ten.at(i).c_str());
		}
	}
private:
	void treeall(vector<string>* bar)
	{
		bar->push_back(name);
		for (auto& entry : children)
			entry.second->treeall(bar);
	}
	void treefirst(int num, vector<string>* bar)
	{
		bar->push_back(name);
		if (--num == 0)return;
		int n = children.size();
		auto it = children.begin();
		while (n--)
		{
			int sts = it->second->tsize;
			if (sts >= num) {
				it->second->treefirst(num, bar);
				return;
			}
			else {
				it->second->treefirst(sts, bar);
				num -= sts;
			}
			it++;
		}
	}
	void treelast(int num, vector<string>* bar)
	{
		int n = children.size();
		auto it = children.end();
		while (n--)
		{
			it--;
			int sts = it->second->tsize;
			if (sts >= num) {
				it->second->treelast(num, bar);
				return;
			}
			else {
				it->second->treelast(sts, bar);
				num -= sts;
			}
		}
		bar->push_back(name);
	}
};
struct command {
	int type;
	Direct* tempdir;
	string arg;
	command(string s) {
		for (int i = 0; i < 7; i++)
		{
			if (c[i] == s)
			{
				type = i; break;
			}
		}
		if (type < 3)
			cin >> temp, arg = temp;
	}
};




void solve() {
	int n;
	cin >> n;
	Direct* now = new Direct("root", NULL);
	vector<command*>cmdlist;
	for (int i = 0; i < n; i++)
	{
		cin >> temp;
		command* cmd = new command(temp);
		int val = cmd->type;   Direct* t;
	    bool su = false;
		switch (val)
		{
		case 0://MKDIR
			t=now->mkdir(cmd->arg);
			if (t == NULL)
				printf("ERR\n");
			else {
				cmd->tempdir =t;
				printf("OK\n");
				//cout <<c[cmd->type]<<": "<< cmd->arg << " " << cmd->tempdir->name << endl;
				cmdlist.push_back(cmd); 
			}
			break;
		case 1://RM
			t=now->rm(cmd->arg);
			if (t == NULL)
				printf("ERR\n");
			else {
				printf("OK\n");
				cmd->tempdir = t;
				//cout << c[cmd->type] << ": " << cmd->arg << " " << cmd->tempdir->name << endl;
				cmdlist.push_back(cmd);
			}
			break;
		case 2://CD.
			t = now->cd(cmd->arg);
			if (t == NULL)
				printf("ERR\n");
			else {
				printf("OK\n");
				cmd->tempdir = now;
				now = t;
				cmdlist.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
		{    
			while (!su && cmdlist.size())
			{
				cmd = cmdlist.back(); cmdlist.pop_back();
				if (cmd->type == 0)
				{
					su = now->rm(cmd->arg) != NULL; break;
				}
				else if (cmd->type == 1)
				{
					//cout << cmd->arg << " " << cmd->tempdir->name << endl;
					su = now->addchild(cmd->tempdir);  break;
				}
				else if (cmd->type == 2)
				{
					now = cmd->tempdir; su = true; break;
				}
			}
			printf(su ? "OK\n" : "ERR\n");
			break;
		}
		}
	}
}




int main() {

	//freopen("out.txt","w",stdout);
	int T; cin >> T;
	while (T--)solve();


	return 0;
}

东东学打牌:
原题链接
这道题也是一道模拟题,只不过比上一道题要简单一些。由于之前做过类似的题目了,做起来还是比较轻松的,但是还是出现了一些不该出现的错误,在写条件的时候复制下去有一个地方忘改了。
大致思路就是对一手牌进行排序,从最大的开始依次判断是否符合条件,符合就返回。然后进行一个多条件排序即可

#include<bits/stdc++.h>
using namespace std;
const int maxn= 1e5+10;
int n;int t[5];int ju[2][3];
struct Play{
	string s;
	int x[5];
	int kind;
}play[maxn];



int rule(Play a,int op)
{
 if(t[0]==1&&t[1]==10&&t[2]==11&&t[3]==12&&t[4]==13)
 {
  ju[op][0]=13;return 8;
 }
 if(t[1]-t[0]==1&&t[2]-t[1]==1&&t[3]-t[2]==1&&t[4]-t[3]==1)
 {
   ju[op][0]=t[4];return 7;
 }
 if((t[0]==t[1]&&t[1]==t[2]&&t[2]==t[3]) || (t[1]==t[2]&&t[2]==t[3]&&t[3]==t[4]))
 {
     if((t[0]==t[1]&&t[1]==t[2]&&t[2]==t[3])) 
	 {
	 ju[op][0]=t[0];ju[op][1]=t[4];
     }
     else if(t[1]==t[2]&&t[2]==t[3]&&t[3]==t[4])
	 {
     ju[op][0]=t[1];ju[op][1]=t[0];
	 }
	 return 6;
 }
 if((t[0]==t[1]&&t[2]==t[3]&&t[3]==t[4]) || (t[0]==t[1]&&t[1]==t[2]&&t[3]==t[4]))
 {
     if(t[0]==t[1]&&t[2]==t[3]&&t[3]==t[4])
	 {
	   	ju[op][0]=t[3];ju[op][1]=t[0];
	 } 
	 else if(t[0]==t[1]&&t[1]==t[2]&&t[3]==t[4])
	 {
	  	ju[op][0]=t[1];ju[op][1]=t[3];
	 }
     return 5;
 }
 if((t[0]==t[1]&&t[1]==t[2]) || (t[1]==t[2]&&t[2]==t[3]) || (t[2]==t[3]&&t[3]==t[4]))
 {
 	
	 if(t[0]==t[1]&&t[1]==t[2])
 	 {
 	    ju[op][0]=t[1];ju[op][1]=t[3]+t[4];	
	 }  
	 else if(t[1]==t[2]&&t[2]==t[3])
	 {
	    ju[op][0]=t[2];ju[op][1]=t[0]+t[4];		
     }
	 else if(t[2]==t[3]&&t[3]==t[4])
	 {
	 	ju[op][0]=t[3];ju[op][1]=t[0]+t[1];	
	 }
 	return 4;
 }
 if((t[0]==t[1]&&t[2]==t[3]) || (t[0]==t[1]&&t[3]==t[4]) || (t[1]==t[2]&&t[3]==t[4]))
 {
    if(t[0]==t[1]&&t[2]==t[3])
    {
    	ju[op][0]=max(t[0],t[2]);ju[op][1]=min(t[0],t[2]);ju[op][2]=t[4];
	}
    else if(t[0]==t[1]&&t[3]==t[4])
    {
    	ju[op][0]=max(t[0],t[3]);ju[op][1]=min(t[0],t[3]);ju[op][2]=t[2];
	}
    else if(t[1]==t[2]&&t[3]==t[4])
    {
    	ju[op][0]=max(t[3],t[2]);ju[op][1]=min(t[3],t[2]);ju[op][2]=t[0];
	}
	return 3;	
 }
 if((t[0]==t[1]) || (t[1]==t[2]) || (t[2]==t[3]) || (t[3]==t[4]))
 {
 	if(t[0]==t[1])
    {
    	ju[op][0]=t[0];ju[op][1]=t[2]+t[3]+t[4];
	}
    else if(t[1]==t[2])
    {
    	ju[op][0]=t[1];ju[op][1]=t[0]+t[3]+t[4];
	}
    else if(t[2]==t[3])
    {
    	ju[op][0]=t[2];ju[op][1]=t[0]+t[1]+t[4];
	}
	else if(t[3]==t[4])
	{
		ju[op][0]=t[3];ju[op][1]=t[0]+t[1]+t[2];
	}
 	return 2;
 }
 else 
 {
 	ju[op][0]=t[0]+t[1]+t[2]+t[3]+t[4];
 	return 1;
 }
}


bool compare(Play &a,Play &b){
	memset(ju,0,sizeof(ju));
for(int i=0;i<5;i++)
  t[i]=a.x[i];
  
  a.kind=rule(a,0);

for(int i=0;i<5;i++)
  t[i]=b.x[i];  
  
  b.kind=rule(b,1); 
if(a.kind!=b.kind)return a.kind>b.kind;
else{
   for(int i=0;i<3;i++)
  {
	if(ju[0][i]!=ju[1][i])
	return ju[0][i]>ju[1][i];
  }	
   return a.s<b.s;
}  	
}


bool cmp(Play a,Play b){
	return compare(a,b);
}

int main(){
while(scanf("%d",&n)!=EOF)
{
	for(int i=0;i<n;i++)
	{
	 play[i].s="";
	 memset(play[i].x,0,sizeof(play[i].x));
	 play[i].kind=0; 
	} 
	memset(t,0,sizeof(t));
	memset(ju,0,sizeof(ju));
	string tt;tt.clear();  int cnt=0;
	for(int i=0;i<n;i++)
	{
		cnt=0;
		cin>>play[i].s>>tt;
	    for(int j=0;;j++)
		 {
		  if(tt[j]=='A') play[i].x[cnt++]=1;
		  else if(tt[j]=='1')play[i].x[cnt++]=10,j++;
		  else if(tt[j]=='J') play[i].x[cnt++]=11;
		  else if(tt[j]=='Q') play[i].x[cnt++]=12;
		  else if(tt[j]=='K') play[i].x[cnt++]=13;
		  else play[i].x[cnt++]=tt[j]-'0';
		  if(cnt==5)break;
	     }
	    sort(play[i].x,play[i].x+5); 
	}
//	for(int i=0;i<n;i++)
//	cout<<play[i].x[0]<<" "<<play[i].x[1]<<" "<<play[i].x[2]<<" "<<play[i].x[3]<<" "<<play[i].x[4]<<" "<<endl;
	sort(play,play+n,cmp);
	for(int i=0;i<n;i++)
    cout<<play[i].s<<endl;
}
	return 0 ;
} 

签到题:
原题链接
签到题,但是wa了好多次,原因是没理解题意……他的mn指的是,来的人坐完之后可能的最小的最大值。

#include<bits/stdc++.h> 
using namespace std;
#define maxn 8
struct soldier{
	int Hp;
	int attack;
	void de(){
		Hp=0;attack=0;
	}
	soldier& operator=(soldier &t)
	{
		Hp=t.Hp;
		attack=t.attack;
		return *this;
	}
};

void battle(soldier &a,soldier &b){
  a.Hp=a.Hp-b.attack;
  b.Hp=b.Hp-a.attack;	
}


class player{
public:
	int Hp;
	soldier s[maxn];
	int numofsoldier;
public:
	player(){
		Hp=30;numofsoldier=0;
	}

	void call(int pos,int att,int hp){
  	    for(int i=numofsoldier+1;i>pos;i--)
		{
		  s[i].Hp=s[i-1].Hp;
	      s[i].attack=s[i-1].attack; 
		 }
		s[pos].Hp=hp;s[pos].attack=att;
		numofsoldier++;
    }
	 
    void judeg_death(int pos){
    	if(s[pos].Hp<=0)
    	{
    	for(int i=pos;i<=numofsoldier;i++)
    	{
		  s[i].Hp=s[i+1].Hp;
	      s[i].attack=s[i+1].attack; 
		 }
    	s[numofsoldier].de();
    	numofsoldier--;
        }
	}
	void attack(player &B,int attacker,int defender){
		if(defender==0)
		{
		    B.Hp=B.Hp-s[attacker].attack;
		}
		else
		{
		   battle(s[attacker],B.s[defender]);
		   //cout<<"ffffff"<<s[attacker].Hp<<" "<<B.s[defender].Hp<<endl;
		   	judeg_death(attacker);
		   	B.judeg_death(defender);
		}
	}
	
		
}; 
int check(player a){
	if(a.Hp<=0)
	{
		return 0;
	}
	else return 1;
}

void solve(){
string op[3]={"summon","attack","end"};
int n=0;cin>>n;
string cmd;
player A[2];
int pid=0;int other=1;
while(n--)
{
	
	cin>>cmd;
   if(cmd==op[0])
   {
   	int at,hp,pos;cin>>pos>>at>>hp;
   	A[pid].call(pos,at,hp);
   }
   else if(cmd==op[1])
   {
   	int at,de;cin>>at>>de;
   	A[pid].attack(A[other],at,de);
   	if(check(A[other])==0)
   	break;
   }
   else if(cmd==op[2])
   {
   	pid=other;other=(pid+1)%2;
   }
}
if(A[0].Hp<=0)cout<<"-1"<<endl;
else if(A[1].Hp<=0)cout<<"1"<<endl;
else cout<<"0"<<endl;

cout<<A[0].Hp<<endl;

cout<<A[0].numofsoldier;
for(int i=1;i<=A[0].numofsoldier;i++)
cout<<" "<<A[0].s[i].Hp;
cout<<endl;

cout<<A[1].Hp<<endl;

cout<<A[1].numofsoldier;
for(int i=1;i<=A[1].numofsoldier;i++)
cout<<" "<<A[1].s[i].Hp;
cout<<endl;
}



int main(){
	solve();
	return 0;
}

实验:
csp2016 09-3 炉石传说:
原题链接
这道题目,也是一道模拟题,思路很清晰,只要玩过类似的游戏都能理解。
具体内容就是实现一个回合制的卡牌游戏(炉石传说),可以将随从进行封装,玩家有若干随从和生命值,也可以封装。
然后就是回合制的操作,攻击召唤判断死亡这一类的简单的函数加进玩家类里就好。

#include<bits/stdc++.h> 
using namespace std;
#define maxn 8
struct soldier{
	int Hp;
	int attack;
	void de(){
		Hp=0;attack=0;
	}
	soldier& operator=(soldier &t)
	{
		Hp=t.Hp;
		attack=t.attack;
		return *this;
	}
};

void battle(soldier &a,soldier &b){
  a.Hp=a.Hp-b.attack;
  b.Hp=b.Hp-a.attack;	
}


class player{
public:
	int Hp;
	soldier s[maxn];
	int numofsoldier;
public:
	player(){
		Hp=30;numofsoldier=0;
	}

	void call(int pos,int att,int hp){
  	    for(int i=numofsoldier+1;i>pos;i--)
		{
		  s[i].Hp=s[i-1].Hp;
	      s[i].attack=s[i-1].attack; 
		 }
		s[pos].Hp=hp;s[pos].attack=att;
		numofsoldier++;
    }
	 
    void judeg_death(int pos){
    	if(s[pos].Hp<=0)
    	{
    	for(int i=pos;i<=numofsoldier;i++)
    	{
		  s[i].Hp=s[i+1].Hp;
	      s[i].attack=s[i+1].attack; 
		 }
    	s[numofsoldier].de();
    	numofsoldier--;
        }
	}
	void attack(player &B,int attacker,int defender){
		if(defender==0)
		{
		    B.Hp=B.Hp-s[attacker].attack;
		}
		else
		{
		   battle(s[attacker],B.s[defender]);
		   //cout<<"ffffff"<<s[attacker].Hp<<" "<<B.s[defender].Hp<<endl;
		   	judeg_death(attacker);
		   	B.judeg_death(defender);
		}
	}
	
		
}; 
int check(player a){
	if(a.Hp<=0)
	{
		return 0;
	}
	else return 1;
}

void solve(){
string op[3]={"summon","attack","end"};
int n=0;cin>>n;
string cmd;
player A[2];
int pid=0;int other=1;
while(n--)
{
	
	cin>>cmd;
   if(cmd==op[0])
   {
   	int at,hp,pos;cin>>pos>>at>>hp;
   	A[pid].call(pos,at,hp);
   }
   else if(cmd==op[1])
   {
   	int at,de;cin>>at>>de;
   	A[pid].attack(A[other],at,de);
   	if(check(A[other])==0)
   	break;
   }
   else if(cmd==op[2])
   {
   	pid=other;other=(pid+1)%2;
   }
}
if(A[0].Hp<=0)cout<<"-1"<<endl;
else if(A[1].Hp<=0)cout<<"1"<<endl;
else cout<<"0"<<endl;

cout<<A[0].Hp<<endl;

cout<<A[0].numofsoldier;
for(int i=1;i<=A[0].numofsoldier;i++)
cout<<" "<<A[0].s[i].Hp;
cout<<endl;

cout<<A[1].Hp<<endl;

cout<<A[1].numofsoldier;
for(int i=1;i<=A[1].numofsoldier;i++)
cout<<" "<<A[1].s[i].Hp;
cout<<endl;
}



int main(){
	solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值