【20200416程序设计思维与实践 CSP月模拟题】炉石传说&元素选择器

目录

    • 201609-3炉石传说
      • 题意
      • 思路
      • 代码
    • 201809-3元素选择器
      • 题意
      • 思路
      • 代码


201609-3炉石传说

题意

【20200416程序设计思维与实践 CSP月模拟题】炉石传说&元素选择器_第1张图片
【20200416程序设计思维与实践 CSP月模拟题】炉石传说&元素选择器_第2张图片


思路

设计两个结构体:随从Minion和玩家Player。为summon和attack操作分别提供两个函数,根据传入的参数决定对某方如何作用。summon通过编辑Player的成员Minion数组完成召唤,attack通过编辑两玩家对应的角色数据并判断更新剩余角色完成攻击。
用一个变量标记当前正在操作的玩家,每当读入“end”时切换玩家。
全部操作完成后,检查双方英雄的生命值,判断胜负并输出相应信息。


代码

#include
#include
using namespace std;

struct Minion{
	int attack;
	int health;
}; 

struct Player{
	int health;
	int msize;
	Minion M[10];
};

Player player[4];

void summon(int ps,int position,int attack,int health){
	if(player[ps].msize!=0&&position<=player[ps].msize)
		for(int i=player[ps].msize;i>=position;i--)//90分的时候反了 
			player[ps].M[i+1]=player[ps].M[i];
	player[ps].M[position].attack=attack;
	player[ps].M[position].health=health;
	player[ps].msize++;
}

void attack(int ps,int po,int id,int object){
	if(object==0)player[po].health-=player[ps].M[id].attack;
	else {
		player[po].M[object].health-=player[ps].M[id].attack;
		player[ps].M[id].health-=player[po].M[object].attack;
		if(player[po].M[object].health<=0){
			if(player[po].msize!=1)
				for(int i=object+1;i<=player[po].msize;i++)
					player[po].M[i-1]=player[po].M[i];
			player[po].msize--;
		}
		if(player[ps].M[id].health<=0){
			if(player[ps].msize!=1)
				for(int i=id+1;i<=player[ps].msize;i++)
					player[ps].M[i-1]=player[ps].M[i];
			player[ps].msize--;
		}
	}
}


int n,Ps,Po;
string ope;
int arg1,arg2,arg3;
void switchTurn(){
	int sp=Ps;
	Ps=Po;
	Po=sp;
}

int main(){
	Ps=1;Po=2;
	player[1].health=player[2].health=30; 
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>ope;
		if(ope=="end"){
			switchTurn();
		}else if(ope=="summon"){
			cin>>arg1>>arg2>>arg3;
			summon(Ps,arg1,arg2,arg3);
		}else if(ope=="attack"){
			cin>>arg1>>arg2;
			attack(Ps,Po,arg1,arg2);
		}
	}
	if(player[1].health<=0)cout<<-1<<endl;
	else if(player[2].health<=0)cout<<1<<endl;
	else cout<<0<<endl;
	cout<<player[1].health<<endl<<player[1].msize;
	for(int i=1;i<=player[1].msize;i++)cout<<" "<<player[1].M[i].health;
	cout<<endl;
	cout<<player[2].health<<endl<<player[2].msize;
	for(int i=1;i<=player[2].msize;i++)cout<<" "<<player[2].M[i].health;
	cout<<endl;
}


201809-3元素选择器

题意

【20200416程序设计思维与实践 CSP月模拟题】炉石传说&元素选择器_第3张图片
【20200416程序设计思维与实践 CSP月模拟题】炉石传说&元素选择器_第4张图片
【20200416程序设计思维与实践 CSP月模拟题】炉石传说&元素选择器_第5张图片


思路

首先要解析输入的结构化文档。用两个变量cur和level记录当前所在的节点和深度,每当一行文档读入,分析字符串中"…"的个数来得到新节点的层数,如果等于当前层则将其连为cur父亲的子,如果大于当前层(此时必大1)则将其连为cur的子,如果小于当前层则按层数回溯到正确的父节点;解析该行文档的标签和id,用结构体将两个信息封装在一起;完成插入后更新cur和level。

接着解析选择器。对于每个选择器,分析其字符串,使其转化为一个向量,向量中的每个成员有字段tag和种类type两个信息,tag由字符串直接复制过来,根据空格分割,根据tag前有无"#"确定type。用DFS遍历整个文档,利用贪心的方式依次匹配向量:对于每一个向量成员,根据它的type决定要匹配的是文档树节点的标签或id,并总是尽量匹配层级小的元素。最坏情况下查询100×10次,所以可以暴力遍历。


代码

#include
#include
#include
using namespace std;

struct choose{
	int type;//0标签,1id 
	string tag; 
};


choose C;
vector<choose> V;
vector<int> V2;

struct node;
struct link{
	link* next;
	int idx;
};
struct node{
	int idx;//在文档中的行数 
	int pa;
	string element;
	string id;
	
	link* child;
	link* tail;
	int sz;
	
	void add(int i){
		link* p=new link;
		p->idx=i;
		p->next=NULL;
		if(sz==0){
			child=p;
			tail=p;
		}else{
			tail->next=p;
			tail=p;
		}
		sz++;
	}
}; 

node CSS[105];

int n,m;
int cur,level;
string str;

int vSize,pv,v2Size;

void dfs(int i){
	if(V[pv].type==0){//元素选择器
		if(CSS[i].element==V[pv].tag){//是 
			if(pv==vSize-1){
				V2.push_back(i);//加入答案向量 
				link* p=CSS[i].child;
				while(p!=NULL){
					dfs(p->idx);
					p=p->next;
				}
			}else{
				link* p=CSS[i].child;
				while(p!=NULL){
					pv++;
					dfs(p->idx);
					pv--;
					p=p->next;
				}
			}
		}else{//否 
			link* p=CSS[i].child;
			while(p!=NULL){
				dfs(p->idx);
				p=p->next;
			}
		} 
	}else{//标签选择器 
		if(CSS[i].id==V[pv].tag){//是 
			if(pv==vSize-1){
				V2.push_back(i);//加入答案向量 
				link* p=CSS[i].child;
				while(p!=NULL){
					dfs(p->idx);
					p=p->next;
				}
			}else{
				link* p=CSS[i].child;
				while(p!=NULL){
					pv++;
					dfs(p->idx);
					pv--;
					p=p->next;
				}
			}
		}else{//否 
			link* p=CSS[i].child;
			while(p!=NULL){
				dfs(p->idx);
				p=p->next;
			}
		} 
	} 
}

int main(){
	cin>>n>>m;
	cin.get();
	cur=-1;
	level=-1;
	for(int i=1;i<=n;i++){
		getline(cin,str);
		int len=str.length();
		int p;
		
		int tempL=0;//层数 
		for(p=0;p<len;p=p+2){
			if(str[p]=='.'&&str[p+1]=='.')tempL++;
			else break;
		}
		 
		char ELE[85];
		char IDX[85];
		int ep,ip;
		ep=ip=0;
		
		for(;p<len;p++){//标签 
			if(str[p]!=' '){
				if(str[p]>='A'&&str[p]<='Z')str[p]=str[p]+32;
				ELE[ep++]=str[p];
			}
			else break;
		}
		string tempE(ELE,ELE+ep);
		
		for(;p<len;p++){//ID 
			if(str[p]==' '||str[p]=='#')continue;
			else IDX[ip++]=str[p];
		}
		string tempI(IDX,IDX+ip);
		
		CSS[i].idx=i;
		CSS[i].element=tempE;
		CSS[i].id=tempI;
		//建起节点 
		
		if(tempL>level){
			if(cur==-1){
				CSS[1].pa=-1;//根节点索引为1 
			}
			else {
				CSS[cur].add(i);
				CSS[i].pa=cur;
			}
			cur=i;
			level=tempL;
		}
		else if(tempL==level){
			CSS[CSS[cur].pa].add(i);
			CSS[i].pa=CSS[cur].pa;
			cur=i;
		}else if(tempL<level){
			while(tempL<level){
				cur=CSS[cur].pa;
				level--;
			}
			CSS[CSS[cur].pa].add(i);
			CSS[i].pa=CSS[cur].pa;
			cur=i;
		}
		//连接 
	}
	
	for(int i=1;i<=m;i++){//m条查询 
		V.clear();
		V2.clear();
		getline(cin,str);
		int len=str.length();
		char tempS[85];
		int cntS=0,rcdP=0;
		C.tag="";
		if(str[0]=='#'){
			C.type=1;
		}else{
			C.type=0;
			if(str[0]>='A'&&str[0]<='Z')str[0]=str[0]+32;
			tempS[cntS++]=str[0];
		} 
		for(int j=1;j<len;j++){
			if(str[j]==' '){
				string temp(tempS+rcdP,tempS+cntS);
				C.tag=temp;
				V.push_back(C);
				
				rcdP=cntS;
				j++;
				if(str[j]=='#'){
					C.type=1;
				//	rcdP++;//rcdP不用++ 
				}else {
					C.type=0;
					if(str[j]>='A'&&str[j]<='Z')str[j]=str[j]+32;
					tempS[cntS++]=str[j];
				}
			}
			else {
				if(C.type==0&&str[j]>='A'&&str[j]<='Z')str[j]=str[j]+32;
				tempS[cntS++]=str[j];
			}
		}
		string temp(tempS+rcdP,tempS+cntS);
		C.tag=temp;
		V.push_back(C);
		vSize=V.size();
		pv=0; 
		dfs(1); 
		
		cout<<V2.size();
		for(int i=0;i<V2.size();i++)cout<<" "<<V2[i];
		cout<<endl;
	} 
}










你可能感兴趣的:(【20200416程序设计思维与实践 CSP月模拟题】炉石传说&元素选择器)