20160903炉石传说

本文详细分析了炉石传说中的一种策略,利用pair记录随从信息,并通过链表存储玩家随从,避免数组频繁修改导致的超时问题。文章介绍了如何处理玩家切换(now=(now+1)%2)、召唤随从、发起攻击等操作的逻辑,并提供了相应的C++代码实现。
摘要由CSDN通过智能技术生成

ccf20160903炉石传说


题目: 炉石传说
这道是一个模拟题,对暴雪的卡牌游戏炉石传说的游戏过程进行模拟,没有啥算法上的难度,只要耐心认真仔细看完所有的注意事项,一步一步按照要求顺序来进行就可以算了

题意分析与思路

这道题我使用pair来进行随从的记录,使用now代表当前的玩家,用一个list链表来保存英雄的随从,因为我觉得这个如果用数组来存可能会因为不停的改变而超时,血量和随从数量也是单独存储

  • 对于end,我就直接处理成了now=(now+1)%2,转换成另一个玩家
  • 如果是summon,我就考虑把输入的随从插到当前玩家的随从池里,我使用了迭代器,由于list这个stl的insert()有一定的特殊性,他会在给出元素的前面插入,所以不能使用这个来插入最后一个,所以我特判最后一个使用push_back,其余的使用insert(it,make_pair(a,b)),将其插入到it的前一个
  • 对于attack,首先判断攻击对象是否是英雄,是的话就对英雄掉血,并且判断是否死亡,攻击的随从不会死亡.如果是随从交换,我们就提取两个随从的迭代器,并且互相伤害,判断是否死亡,死亡就使用list里的erase
    输出就按照题目要求就好

代码

#include<iostream>
#include<list>
#include<string>
#include<cstring>
using namespace std;
const int nmax=5E4+10;
list<pair<int,int> > hero[2];
int now=0,player[2],blood[2];
char oper[20];
list<pair<int,int> >::iterator get_iter(int p,int pos){
	auto iter=hero[p].begin(),stop=hero[p].end();
	for(int i=1;i<pos;++i) if((++iter)==stop){  iter--;break;}
	return iter;
}
void sum(int pos,int a,int b){
	if(pos==hero[now].size()+1){hero[now].push_back(make_pair(a,b));return ;}
	auto it=get_iter(now,pos);
	hero[now].insert(it,make_pair(a,b));
}
void init(){
	fill(blood,blood+2,30);
	fill(player,player+2,0);
	now=0;
}
int main(){
	int flag=0;//0号die flag=2,1号die flag=1
	int num;scanf("%d",&num);
	init();
	for(int i=0;i<num;++i){
		scanf("%s",oper);
		if(oper[0]=='a'){
			int p0,p1;scanf("%d%d",&p0,&p1);
			if(p1==0){
				int tar=1-now;
				blood[tar]-=get_iter(now,p0)->first;
				if(blood[tar]<=0) {flag=2-tar;break;}
				continue;
			}
			int att=now,def=1-now;
			auto it0=get_iter(now,p0),it1=get_iter(def,p1);
			it0->second-=it1->first;
			it1->second-=it0->first;
			if(it0->second<=0){
				hero[now].erase(it0);
				player[now]--;
			}
			if(it1->second<=0){
				hero[def].erase(it1);
				player[def]--;
			}
		}
		else if(oper[0]=='e'){
			now=(now+1)%2;
		}
		else if(oper[0]=='s'){
			int pos,x,y;
			scanf("%d%d%d",&pos,&x,&y);
			if(player[now]<7) {sum(pos,x,y);player[now]++;}
		}
	}
	//output
	switch (flag){
		case 0:{ printf("0\n");break;}
		case 1:{ printf("1\n");break;}
		case 2:{ printf("-1\n");break;}
		//default:{printf("0\n");}
	}
	for(int i=0;i<=1;++i){
		printf("%d\n%d",blood[i],player[i]);
		for(auto it=hero[i].begin();it!=hero[i].end();++it){
			printf(" %d",it->second);
		}
		printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值