咕咕东的目录管理器、东东学打牌 、签到题、炉石传说
作业:
咕咕东的目录管理器:
原题链接
题意大概就是模拟一个类似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;
}