魔兽世界终极版


题目:

魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 .... N ( N <= 20 )。红魔军的司令部算作编号为0的城市,蓝魔军的司令部算作编号为N+1的城市。司令部有生命元,用于制造武士。

两军的司令部都会制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值、攻击力这三种属性。

双方的武士编号都是从1开始计算。红方制造出来的第 n 个武士,编号就是n。同样,蓝方制造出来的第 n 个武士,编号也是n。

武士在刚降生的时候有一个初始的生命值,生命值在战斗中会发生变化,如果生命值减少到0(生命值变为负数时应当做变为0处理),则武士死亡(消失)。

有的武士可以拥有武器。武器有三种,sword, bomb,和arrow,编号分别为0,1,2。

武士降生后就朝对方司令部走,在经过的城市如果遇到敌人(同一时刻每个城市最多只可能有1个蓝武士和一个红武士),就会发生战斗。每次战斗只有一方发起主动进攻一次。被攻击者生命值会减去进攻者的攻击力值和进攻者手中sword的攻击力值。被进攻者若没死,就会发起反击,被反击者的生命值要减去反击者攻击力值的一半(去尾取整)和反击者手中sword的攻击力值。反击可能致敌人于死地。

如果武士在战斗中杀死敌人(不论是主动进攻杀死还是反击杀死),则其司令部会立即向其发送8个生命元作为奖励,使其生命值增加8。当然前提是司令部得有8个生命元。如果司令部的生命元不足以奖励所有的武士,则优先奖励距离敌方司令部近的武士。

如果某武士在某城市的战斗中杀死了敌人,则该武士的司令部立即取得该城市中所有的生命元。注意,司令部总是先完成全部奖励工作,然后才开始从各个打了胜仗的城市回收生命元。对于因司令部生命元不足而领不到奖励的武士,司令部也不会在取得战利品生命元后为其补发奖励。

如果一次战斗的结果是双方都幸存(平局),则双方都不能拿走发生战斗的城市的生命元。

城市可以插旗子,一开始所有城市都没有旗子。在插红旗的城市,以及编号为奇数的无旗城市,由红武士主动发起进攻。在插蓝旗的城市,以及编号为偶数的无旗城市,由蓝武士主动发起进攻。

当某个城市有连续两场战斗都是同一方的武士杀死敌人(两场战斗之间如果有若干个战斗时刻并没有发生战斗,则这两场战斗仍然算是连续的;但如果中间有平局的战斗,就不算连续了) ,那么该城市就会插上胜方的旗帜,若原来插着败方的旗帜,则败方旗帜落下。旗帜一旦插上,就一直插着,直到被敌人更换。一个城市最多只能插一面旗帜,旗帜没被敌人更换前,也不会再次插同颜色的旗。

各种武器有其特点:

sword武器的初始攻击力为拥有它的武士的攻击力的20%(去尾取整)。但是sword每经过一次战斗(不论是主动攻击还是反击),就会变钝,攻击力变为本次战斗前的80% (去尾取整)。sword攻击力变为0时,视为武士失去了sword。如果武士降生时得到了一个初始攻击力为0的sword,则视为武士没有sword.

arrow有一个攻击力值R。如果下一步要走到的城市有敌人,那么拥有arrow的武士就会放箭攻击下一个城市的敌人(不能攻击对方司令部里的敌人)而不被还击。arrow使敌人的生命值减少R,若减至小于等于0,则敌人被杀死。arrow使用3次后即被耗尽,武士失去arrow。两个相邻的武士可能同时放箭把对方射死。

拥有bomb的武士,在战斗开始前如果判断自己将被杀死(不论主动攻击敌人,或者被敌人主动攻击都可能导致自己被杀死,而且假设武士可以知道敌人的攻击力和生命值),那么就会使用bomb和敌人同归于尽。武士不预测对方是否会使用bomb。

武士使用bomb和敌人同归于尽的情况下,不算是一场战斗,双方都不能拿走城市的生命元,也不影响城市的旗帜。

不同的武士有不同的特点。

dragon可以拥有一件武器。编号为n的dragon降生时即获得编号为 n%3 的武器。dragon还有“士气”这个属性,是个浮点数,其值为它降生后其司令部剩余生命元的数量除以造dragon所需的生命元数量。dragon 在一次在它主动进攻的战斗结束后,如果还没有战死,而且士气值大于0.8,就会欢呼。dragon每取得一次战斗的胜利(敌人被杀死),士气就会增加0.2,每经历一次未能获胜的战斗,士气值就会减少0.2。士气增减发生在欢呼之前。

ninja可以拥有两件武器。编号为n的ninja降生时即获得编号为 n%3 和 (n+1)%3的武器。ninja 挨打了也从不反击敌人。

iceman有一件武器。编号为n的iceman降生时即获得编号为 n%3 的武器。iceman 每前进两步,在第2步完成的时候,生命值会减少9,攻击力会增加20。但是若生命值减9后会小于等于0,则生命值不减9,而是变为1。即iceman不会因走多了而死。

lion 有“忠诚度”这个属性,其初始值等于它降生之后其司令部剩余生命元的数目。每经过一场未能杀死敌人的战斗,忠诚度就降低K。忠诚度降至0或0以下,则该lion逃离战场,永远消失。但是已经到达敌人司令部的lion不会逃跑。Lion在己方司令部可能逃跑。lion 若是战死,则其战斗前的生命值就会转移到对手身上。所谓“战斗前”,就是每个小时的40分前的一瞬间。

wolf降生时没有武器,但是在战斗中如果获胜(杀死敌人),就会缴获敌人的武器,但自己已有的武器就不缴获了。被缴获的武器当然不能算新的,已经被用到什么样了,就是什么样的。

以下是不同时间会发生的不同事件:

在每个整点,即每个小时的第0分, 双方的司令部中各有一个武士降生。

红方司令部按照 iceman、lion、wolf、ninja、dragon 的顺序制造武士。

蓝方司令部按照 lion、dragon、ninja、iceman、wolf 的顺序制造武士。

制造武士需要生命元。

制造一个初始生命值为 m 的武士,司令部中的生命元就要减少 m 个。

如果司令部中的生命元不足以制造某武士,那么司令部就等待,直到获得足够生命元后的第一个整点,才制造该武士。例如,在2:00,红方司令部本该制造一个 wolf ,如果此时生命元不足,那么就会等待,直到生命元足够后的下一个整点,才制造一个 wolf。

在每个小时的第5分,该逃跑的lion就在这一时刻逃跑了。

在每个小时的第10分:所有的武士朝敌人司令部方向前进一步。即从己方司令部走到相邻城市,或从一个城市走到下一个城市。或从和敌军司令部相邻的城市到达敌军司令部。

在每个小时的第20分:每个城市产出10个生命元。生命元留在城市,直到被武士取走。

在每个小时的第30分:如果某个城市中只有一个武士,那么该武士取走该城市中的所有生命元,并立即将这些生命元传送到其所属的司令部。

在每个小时的第35分,拥有arrow的武士放箭,对敌人造成伤害。放箭事件应算发生在箭发出的城市。注意,放箭不算是战斗,因此放箭的武士不会得到任何好处。武士在没有敌人的城市被箭射死也不影响其所在城市的旗帜更换情况。

在每个小时的第38分,拥有bomb的武士评估是否应该使用bomb。如果是,就用bomb和敌人同归于尽。

在每个小时的第40分:在有两个武士的城市,会发生战斗。 如果敌人在5分钟前已经被飞来的arrow射死,那么仍然视为发生了一场战斗,而且存活者视为获得了战斗的胜利。此情况下不会有“武士主动攻击”,“武士反击”,“武士战死”的事件发生,但战斗胜利后应该发生的事情都会发生。如Wolf一样能缴获武器,旗帜也可能更换,等等。在此情况下,Dragon同样会通过判断是否应该轮到自己主动攻击来决定是否欢呼。

在每个小时的第50分,司令部报告它拥有的生命元数量。

在每个小时的第55分,每个武士报告其拥有的武器情况。

武士到达对方司令部后就算完成任务了,从此就呆在那里无所事事。

任何一方的司令部里若是出现了2个敌人,则认为该司令部已被敌人占领。

任何一方的司令部被敌人占领,则战争结束。战争结束之后就不会发生任何事情了。

给定一个时间,要求你将从0点0分开始到此时间为止的所有事件按顺序输出。事件及其对应的输出样例如下:


1) 武士降生

输出样例: 000:00 blue lion 1 born

表示在 0点0分,编号为1的蓝魔lion武士降生
如果造出的是dragon,那么还要多输出一行,例:

000:00 blue dragon 1 born
Its morale is 23.34

表示该该dragon降生时士气是23. 34(四舍五入到小数点后两位)

如果造出的是lion,那么还要多输出一行,例:
000:00 blue lion 1 born
Its loyalty is 24

表示该lion降生时的忠诚度是24

2) lion逃跑

输出样例: 000:05 blue lion 1 ran away
表示在 0点5分,编号为1的蓝魔lion武士逃走

3) 武士前进到某一城市

输出样例: 000:10 red iceman 1 marched to city 1 with 20 elements and force 30
表示在 0点10分,红魔1号武士iceman前进到1号城市,此时他生命值为20,攻击力为30
对于iceman,输出的生命值和攻击力应该是变化后的数值

4)武士放箭

输出样例: 000:35 blue dragon 1 shot
表示在 0点35分,编号为1的蓝魔dragon武士射出一支箭。如果射出的箭杀死了敌人,则应如下输出:
000:35 blue dragon 1 shot and killed red lion 4
表示在 0点35分,编号为1的蓝魔dragon武士射出一支箭,杀死了编号为4的红魔lion。

5)武士使用bomb

输出样例: 000:38 blue dragon 1 used a bomb and killed red lion 7
表示在 0点38分,编号为1的蓝魔dragon武士用炸弹和编号为7的红魔lion同归于尽。

6) 武士主动进攻

输出样例:000:40 red iceman 1 attacked blue lion 1 in city 1 with 20 elements and force 30
表示在0点40分,1号城市中,红魔1号武士iceman 进攻蓝魔1号武士lion,在发起进攻前,红魔1号武士iceman生命值为20,攻击力为 30

7) 武士反击

输出样例:001:40 blue dragon 2 fought back against red lion 2 in city 1
表示在1点40分,1号城市中,蓝魔2号武士dragon反击红魔2号武士lion

8) 武士战死

输出样例:001:40 red lion 2 was killed in city 1
被箭射死的武士就不会有这一条输出。

9) 武士欢呼

输出样例:003:40 blue dragon 2 yelled in city 4

10) 武士获取生命元( elements )

输出样例:001:40 blue dragon 2 earned 10 elements for his headquarter

输出不包括在30分不是通过战斗获取的elements

11) 旗帜升起

输出样例:004:40 blue flag raised in city 4

12) 武士抵达敌军司令部

输出样例:001:10 red iceman 1 reached blue headquarter with 20 elements and force 30
(此时他生命值为20,攻击力为30)对于iceman,输出的生命值和攻击力应该是变化后的数值

13) 司令部被占领

输出样例:003:10 blue headquarter was taken

14)司令部报告生命元数量

000:50 100 elements in red headquarter
000:50 120 elements in blue headquarter
表示在0点50分,红方司令部有100个生命元,蓝方有120个

15)武士报告武器情况

000:55 blue wolf 2 has arrow(2),bomb,sword(23)
000:55 blue wolf 4 has no weapon
000:55 blue wolf 5 has sword(20)
表示在0点55分,蓝魔2号武士wolf有一支arrow(这支arrow还可以用2次),一个bomb,还有一支攻击力为23的sword。
蓝魔4号武士wolf没武器。
蓝魔5号武士wolf有一支攻击力为20的sword。
交代武器情况时,次序依次是:arrow,bomb,sword。如果没有某种武器,某种武器就不用提。报告时,先按从西向东的顺序所有的红武士报告,然后再从西向东所有的蓝武士报告。

输出事件时:

首先按时间顺序输出;

同一时间发生的事件,按发生地点从西向东依次输出. 武士前进的事件, 算是发生在目的地。

在一次战斗中有可能发生上面的 6 至 11 号事件。这些事件都算同时发生,其时间就是战斗开始时间。一次战斗中的这些事件,序号小的应该先输出。

两个武士同时抵达同一城市,则先输出红武士的前进事件,后输出蓝武士的。

显然,13号事件发生之前的一瞬间一定发生了12号事件。输出时,这两件事算同一时间发生,但是应先输出12号事件

虽然任何一方的司令部被占领之后,就不会有任何事情发生了。但和司令部被占领同时发生的事件,全都要输出。

输入

第一行是t,代表测试数据组数
每组样例共三行。
第一行,五个整数 M,N,R,K, T。其含义为:

每个司令部一开始都有M个生命元( 1 <= M <= 10000)
两个司令部之间一共有N个城市( 1 <= N <= 20 )
arrow的攻击力是R
lion每经过一场未能杀死敌人的战斗,忠诚度就降低K。
要求输出从0时0分开始,到时间T为止(包括T) 的所有事件。T以分钟为单位,0 <= T <= 5000

第二行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它们都大于0小于等于10000

第三行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的攻击力。它们都大于0小于等于10000

输出

对每组数据,先输出一行:
Case n:
如对第一组数据就输出 Case1:
然后按恰当的顺序和格式输出到时间T为止发生的所有事件。每个事件都以事件发生的时间开头,时间格式是“时: 分”,“时”有三位,“分”有两位。

分析:  
1.    基本的类定义和部分函数定义可以延续魔兽3;

2.    city结构体中加入flag,fightrecord变量,记录旗帜的升降;
3.    注意司令部生命元能增加,因此每一轮都可能制造武士;
4.    射箭的动作和输出顺序不一致,需要合理解决;

代码:
//#define LOCAL
#include<cstdio>
#include<iostream>
#include<string>
#include<sstream>
#include<iomanip>
#include<cmath>
#include<set>
using namespace std;

//attention to initialize data for every test data
const string weap[3] = {"sword", "bomb", "arrow"};
int blue_ord[5] = {4,1,2,3,5};  //blue headquarter order: lion,dragon,ninja,iceman,wolf
int red_ord[5] = {3,4,5,2,1};   //red headquarter order: iceman,lion,wolf,ninja,dragon
int ini_life[6];    //lif[1~5] refers to initial life of dragon 、ninja、iceman、lion、wolf
int AttackForce[6];   //AttackForce for dragon 、ninja、iceman、lion、wolf
int LoyaltyDecrease;   //loyalty decreasing every step for a lion
int Hour=0;
bool MainFlag=1;   //judge whether a headquarter is taken
int ArrowForce;   //Arrow
set<int> RedAward;
set<int> BlueAward;   //using two sets to storage award result

//standard form of time output
void show_hour() {
	cout<<setw(3)<<setfill('0')<<Hour;
}

//number to string
string n_to_s (int n) {
	string res;
	stringstream ss;
	ss << n;
	ss >> res;
	return res;
}

//weapons belong to a warrior
class weaponList {
	public:
		int Weap[3];
		int SwordForce;
		int ArrowNum;
		weaponList(): SwordForce(0), ArrowNum(0) {
			for (int i=0; i<3; ++i) Weap[i]=0;
		}
		weaponList(int n1): SwordForce(0), ArrowNum(0) {
			for (int i=0; i<3; ++i) Weap[i]=0;
			Weap[n1]++;
			if (n1==2) ArrowNum=3;
		}
		weaponList(int n1, int n2): SwordForce(0), ArrowNum(0) {
			for (int i=0; i<3; ++i) Weap[i]=0;
			Weap[n1]++;
			Weap[n2]++;
			if (n1==2 || n2==2) ArrowNum=3;
		}
		void weap_show () {
			cout<<Weap[0]<<"sword "<<SwordForce<<"swordforce "<<Weap[1]<<"bomb "<<Weap[2]<<"arrow "<<ArrowNum<<"arrow left"<<endl;
		} //for debug
};

//warrior class
class warrior {
	public:
		string Name;
		string Head;
		int Number;
		int Life;
		int Attack;
		weaponList weapons;
		double Morale;
		int IcemanStep;
		int Loyalty;
		bool getShot;
		warrior(string s, string h, int n1, int n2, int n3): weapons(), Name(s), Head(h), Number(n1), Life(n2), Attack(n3), getShot(0) {}
		warrior(string s, string h, int n1, int n2, int n3, int n4_1): weapons(n4_1), Name(s), Head(h), Number(n1), Life(n2), Attack(n3), getShot(0) {
			if (n4_1==0) weapons.SwordForce=n3/5;
		}
		warrior(string s, string h, int n1, int n2, int n3, int n4_1, int n4_2): weapons(n4_1, n4_2), Name(s), Head(h), Number(n1), Life(n2), Attack(n3), getShot(0) {
			if (n4_1==0 || n4_2==0) weapons.SwordForce=n3/5;
		}
		// 3 different constructor for all kinds of warriors.
		//debug
		void showWarrior () {
			cout<<"Name:"<<Name<<" Head:"<<Head<<" Number:"<<Number<<" Life:"<<Life<<" Attack:"<<Attack<<endl;
			weapons.weap_show();
		} //for debug
		virtual bool LionEscape() {
			return 0;
		}
};

class Dragon: public warrior {
	public:
		Dragon (string s, string h, int n1, int n2, int n3, int n4_1, double d): warrior(s, h, n1, n2, n3, n4_1) {
		    Morale=d;
		}
};
class Ninja: public warrior {
	public:
		Ninja (string s, string h, int n1, int n2, int n3, int n4_1, int n4_2): warrior(s, h, n1, n2, n3, n4_1, n4_2) {}
};
class Iceman: public warrior {
	public:
		Iceman (string s, string h, int n1, int n2, int n3, int n4_1): warrior(s, h, n1, n2, n3, n4_1) {
		    IcemanStep=0;
		}
};
class Lion: public warrior {
	public:
		Lion(string s, string h, int n1, int n2, int n3, int n5): warrior(s, h, n1, n2, n3) {
		    Loyalty=n5;
		}
		bool LionEscape() {
			if (Loyalty>0) return 0;
			show_hour();
			cout<<":05 "<<Head<<" lion "<<Number<<" ran away"<<endl;
			//delete this;
			return 1;
		} //judge whether the lion escapes
};
class Wolf: public warrior {
	public:
		Wolf (string s, string h, int n1, int n2, int n3): warrior(s, h, n1, n2, n3) {}
};

//city
struct City {
	string CityName;
	warrior *redwarrior;
	warrior *bluewarrior;
	warrior *tempred;
	warrior *tempblue; //temporary pointer to warriors, remember to transform after move!
	bool isHead;
	int FightRecord; //+i means red wins constantly, -i means blue wins constantly
	int CityFlag; //1 means red flag, -1 means blue flag, 0 means no flag
	int CityLife;
	City(string s="", bool b=0): CityName(s), redwarrior(NULL), bluewarrior(NULL), tempred(NULL), tempblue(NULL), isHead(b), FightRecord(0), CityFlag(0), CityLife(0) {
	}
}; //attention to initialization!

//headquarter class
class Headquarter {
	public:
		string Hname;
		int lifeunit;
		int warrior_num;
		int scanner;
		int scan_order[5];
		Headquarter(string s, int n1,  int *arr): Hname(s), lifeunit(n1), warrior_num(0), scanner(-1) {
			for (int i=0; i<5; ++i) scan_order[i]=arr[i];
		}
};

//headquarter produce a warrior
void producing (warrior* &pointer, Headquarter &headquarter) {
	headquarter.scanner++;
	if (headquarter.lifeunit<ini_life[headquarter.scan_order[headquarter.scanner%5]]) {
		headquarter.scanner--;
		return;
	}
	int res=headquarter.scan_order[headquarter.scanner%5];
	++headquarter.warrior_num;
	headquarter.lifeunit-=ini_life[res];
	show_hour();
	cout<<":00 "<<headquarter.Hname<<' ';
	switch (res) {
		case 1: {
			pointer=new Dragon("dragon",headquarter.Hname,headquarter.warrior_num,ini_life[1],AttackForce[1],headquarter.warrior_num%3,double(headquarter.lifeunit)/double(ini_life[1]));
			cout<<"dragon ";
			cout<<headquarter.warrior_num<<" born"<<endl;
			cout<<"Its morale is "<<setiosflags(ios::fixed)<<setprecision(2)<<pointer->Morale<<endl;
			break;
		}
		case 2: {
			pointer=new Ninja("ninja",headquarter.Hname,headquarter.warrior_num,ini_life[2],AttackForce[2],headquarter.warrior_num%3,(headquarter.warrior_num+1)%3);
			cout<<"ninja ";
			cout<<headquarter.warrior_num<<" born"<<endl;
			break;
		}
		case 3: {
			pointer=new Iceman("iceman",headquarter.Hname,headquarter.warrior_num,ini_life[3],AttackForce[3],headquarter.warrior_num%3);
			cout<<"iceman ";
			cout<<headquarter.warrior_num<<" born"<<endl;
			break;
		}
		case 4: {
			pointer=new Lion("lion",headquarter.Hname,headquarter.warrior_num,ini_life[4],AttackForce[4],headquarter.lifeunit);
			cout<<"lion ";
			cout<<headquarter.warrior_num<<" born"<<endl;
			cout<<"Its loyalty is "<<headquarter.lifeunit<<endl;
			break;
		}
		case 5: {
			pointer=new Wolf("wolf",headquarter.Hname,headquarter.warrior_num,ini_life[5],AttackForce[5]);
			cout<<"wolf ";
			cout<<headquarter.warrior_num<<" born"<<endl;
			break;
		}
		default: {
			break;
		}
	}
}

//move function for a single destination .
void warriorMove (City* destination, City* leftCity, City* rightCity) {

	if (leftCity->redwarrior) {
		if (leftCity->redwarrior->Name=="iceman") {
			if (leftCity->redwarrior->IcemanStep==0) {
				++leftCity->redwarrior->IcemanStep;
			}
			else {
				leftCity->redwarrior->IcemanStep=0;
				leftCity->redwarrior->Attack+=20;
				if (leftCity->redwarrior->Life>9) leftCity->redwarrior->Life-=9;
				else leftCity->redwarrior->Life=1;
			}
		}
		show_hour();
		if (!(destination->isHead)) {
			cout<<":10 "<<"red "<<leftCity->redwarrior->Name<<" "<<leftCity->redwarrior->Number<<" marched to city "
			    <<destination->CityName<<" with "<<leftCity->redwarrior->Life<<" elements and force "
			    <<leftCity->redwarrior->Attack<<endl;
		} else if (destination->isHead) {
			cout<<":10 "<<"red "<<leftCity->redwarrior->Name<<" "<<leftCity->redwarrior->Number<<" reached blue headquarter with "
			    <<leftCity->redwarrior->Life<<" elements and force "<<leftCity->redwarrior->Attack<<endl;
			if (destination->redwarrior) {
                show_hour();
                cout<<":10 blue headquarter was taken"<<endl;
                MainFlag=0;
			}
		}
		destination->tempred = leftCity->redwarrior;
		leftCity->redwarrior=NULL;
	}


	if (rightCity->bluewarrior) {
		if (rightCity->bluewarrior->Name=="iceman")  {
			if (rightCity->bluewarrior->IcemanStep==0) {
				++rightCity->bluewarrior->IcemanStep;
			}
			else {
				rightCity->bluewarrior->IcemanStep=0;
				rightCity->bluewarrior->Attack+=20;
				if (rightCity->bluewarrior->Life>9) rightCity->bluewarrior->Life-=9;
				else rightCity->bluewarrior->Life=1;
			}
		}
		show_hour();
		if (!(destination->isHead)) {
			cout<<":10 "<<"blue "<<rightCity->bluewarrior->Name<<" "<<rightCity->bluewarrior->Number<<" marched to city "
			    <<destination->CityName<<" with "<<rightCity->bluewarrior->Life<<" elements and force "
			    <<rightCity->bluewarrior->Attack<<endl;
		} else if(destination->isHead) {
			cout<<":10 "<<"blue "<<rightCity->bluewarrior->Name<<" "<<rightCity->bluewarrior->Number<<" reached red headquarter with "
			    <<rightCity->bluewarrior->Life<<" elements and force "<<rightCity->bluewarrior->Attack<<endl;
			if (destination->bluewarrior) {
                show_hour();
			    cout<<":10 red headquarter was taken"<<endl;
                MainFlag=0;
			}
		}
		destination->tempblue = rightCity->bluewarrior;
		rightCity->bluewarrior=NULL;
	}

}

//all the warriors move in order
void allWarriorMove (City* cityArray, int start, int end) {
	for (int i=start; i<=end; ++i) warriorMove(&cityArray[i], &cityArray[i-1], &cityArray[i+1]);
}

//move warriors to correct place in a city
void warriorPlace (City* destination) {
	if (destination->tempblue) {
		destination->bluewarrior=destination->tempblue;
		destination->tempblue=NULL;
	}
	if (destination->tempred) {
		destination->redwarrior=destination->tempred;
		destination->tempred=NULL;
	}
}

//single warrior gets element for its headquarter
void getElement (City* cit, Headquarter &red, Headquarter &blue) {
	if (cit->redwarrior && !(cit->bluewarrior)) {
		show_hour();
		cout<<":30 red "<<cit->redwarrior->Name<<" "<<cit->redwarrior->Number<<" earned "<<cit->CityLife<<" elements for his headquarter"<<endl;
		red.lifeunit+=cit->CityLife;
		cit->CityLife=0;
	}
	else if(cit->bluewarrior && !(cit->redwarrior)) {
		show_hour();
		cout<<":30 blue "<<cit->bluewarrior->Name<<" "<<cit->bluewarrior->Number<<" earned "<<cit->CityLife<<" elements for his headquarter"<<endl;
		blue.lifeunit+=cit->CityLife;
		cit->CityLife=0;
	}
}

//warrior with arrow shoot warrior next city
void shot (City* middleCity, City* leftCity, City* rightCity) {
	if (middleCity->redwarrior) {
		if (middleCity->redwarrior->weapons.ArrowNum&& !(rightCity->isHead) &&rightCity->bluewarrior) {
			middleCity->redwarrior->weapons.ArrowNum--;
			if (middleCity->redwarrior->weapons.ArrowNum==0) middleCity->redwarrior->weapons.Weap[2]=0;
			rightCity->bluewarrior->Life-=ArrowForce;
			if (rightCity->bluewarrior->Life<=0) {
				show_hour();
				cout<<":35 red "<<middleCity->redwarrior->Name<<" "<<middleCity->redwarrior->Number<<" shot and killed blue "<<
				    rightCity->bluewarrior->Name<<" "<<rightCity->bluewarrior->Number<<endl;
				rightCity->bluewarrior->getShot=1;
			}
			else {
				show_hour();
				cout<<":35 red "<<middleCity->redwarrior->Name<<" "<<middleCity->redwarrior->Number<<" shot"<<endl;
			}
		}
	}

	if (middleCity->bluewarrior) {
		if (middleCity->bluewarrior->weapons.ArrowNum&&!(leftCity->isHead) &&leftCity->redwarrior) {
			middleCity->bluewarrior->weapons.ArrowNum--;
			if (middleCity->bluewarrior->weapons.ArrowNum==0) middleCity->bluewarrior->weapons.Weap[2]=0;
			leftCity->redwarrior->Life-=ArrowForce;
			if (leftCity->redwarrior->Life<=0) {
				show_hour();
				cout<<":35 blue "<<middleCity->bluewarrior->Name<<" "<<middleCity->bluewarrior->Number<<" shot and killed red "<<
				    leftCity->redwarrior->Name<<" "<<leftCity->redwarrior->Number<<endl;
				leftCity->redwarrior->getShot=1;
			}
			else {
				show_hour();
				cout<<":35 blue "<<middleCity->bluewarrior->Name<<" "<<middleCity->bluewarrior->Number<<" shot"<<endl;
			}
		}
	}
}

//move warriors killed by arrow to temp places
void Arr_Kill_move (City *cit) {
    if (cit->redwarrior && cit->redwarrior->getShot) {
        cit->tempred=cit->redwarrior;
        cit->redwarrior=NULL;
    }
    if (cit->bluewarrior && cit->bluewarrior->getShot) {
        cit->tempblue=cit->bluewarrior;
        cit->bluewarrior=NULL;
    }
}

//judge whether a warrior dies in the next battle; if red dies, return 1, if blue dies, return -1, otherwise return 0
int battle_judge (City* cit, int city_num) {
	if (! (cit->redwarrior&&cit->bluewarrior) ) return 0;
	int redlife=cit->redwarrior->Life, bluelife=cit->bluewarrior->Life, redattack=cit->redwarrior->Attack,
	    blueattack=cit->bluewarrior->Attack, redsword=cit->redwarrior->weapons.SwordForce, bluesword=cit->bluewarrior->weapons.SwordForce;
	if (cit->redwarrior->weapons.Weap[0]==0) redsword=0;
	if (cit->bluewarrior->weapons.Weap[0]==0) bluesword=0;

	if (cit->CityFlag==1 || cit->CityFlag==0&&city_num%2==1) {
		bluelife-=(redattack+redsword);
		if (bluelife<=0) return -1;
		if (cit->bluewarrior->Name=="ninja") return 0;
		redlife-=(blueattack/2+bluesword);
		if (redlife<=0) return 1;
	}
	else {
		redlife-=(blueattack+bluesword);
		if (redlife<=0) return 1;
		if (cit->redwarrior->Name=="ninja") return 0;
		bluelife-=(redattack/2+redsword);
		if (bluelife<=0) return -1;
	}
	return 0;
}

//using a bomb
void bomb_using (City *cit, int city_num) {
	if (cit->redwarrior && cit->bluewarrior) {
		int fla=battle_judge(cit, city_num);
		if (fla==1 && cit->redwarrior->weapons.Weap[1]) {
			show_hour();
			cout<<":38 red "<<cit->redwarrior->Name<<" "<<cit->redwarrior->Number<<" used a bomb and killed blue "
			    <<cit->bluewarrior->Name<<" "<<cit->bluewarrior->Number<<endl;
			delete cit->redwarrior; delete cit->bluewarrior;
			cit->redwarrior=NULL; cit->bluewarrior=NULL;
		}
		else if (fla==-1 && cit->bluewarrior->weapons.Weap[1]) {
			show_hour();
			cout<<":38 blue "<<cit->bluewarrior->Name<<" "<<cit->bluewarrior->Number<<" used a bomb and killed red "
			    <<cit->redwarrior->Name<<" "<<cit->redwarrior->Number<<endl;
			delete cit->redwarrior; delete cit->bluewarrior;
			cit->redwarrior=NULL; cit->bluewarrior=NULL;
		}
	}
}

//calculate the award; by the way, clear warriors killed by arrow
void Award_Cal (City *cit, int cityNumber, int redLU, int blueLU) {
	RedAward.clear();
	BlueAward.clear();
	for (int i=2; i<=cityNumber+1; ++i) {
		if ( cit[i].tempblue && cit[i].tempred) {
			delete cit[i].tempblue; delete cit[i].tempred;
			cit[i].tempblue=NULL; cit[i].tempred=NULL;
		}
		else if (cit[i].tempblue && !(cit[i].redwarrior)) {
            delete cit[i].tempblue; cit[i].tempblue=NULL;
		}
		else if (cit[i].tempred && !(cit[i].bluewarrior)) {
            delete cit[i].tempred; cit[i].tempred=NULL;
		}
		else if (cit[i].bluewarrior && cit[i].tempred || battle_judge(&cit[i],i-1)==1) {
			if (blueLU>=8) {
				blueLU-=8;
				BlueAward.insert(i-1);
			}
			else break;
		}
	}
	for (int i=cityNumber+1; i>=2; --i) {
		if (cit[i].redwarrior && cit[i].tempblue || battle_judge(&cit[i],i-1)==-1) {
			if (redLU>=8) {
				redLU-=8;
				RedAward.insert(i-1);
			}
			else break;
		}
	}
}

//wolf capture
void capture (warrior *wolf0, warrior *dead) {
	if (wolf0->Name=="wolf")
	for (int i=0; i<3; ++i) {
		if (wolf0->weapons.Weap[i]==0 && dead->weapons.Weap[i]!=0) {
			wolf0->weapons.Weap[i]=1;
			if (i==0) wolf0->weapons.SwordForce=dead->weapons.SwordForce;
			else if(i==2) wolf0->weapons.ArrowNum=dead->weapons.ArrowNum;
		}
	}
}

//battle in a city
void battling (City *cit, int city_num, Headquarter &red, Headquarter &blue) {
	if (cit->redwarrior && cit->tempblue) {
		if (cit->redwarrior->Name=="wolf") capture(cit->redwarrior, cit->tempblue);
		else if (cit->redwarrior->Name=="dragon") {
			cit->redwarrior->Morale+=0.2;
			if ( (cit->CityFlag==1 || cit->CityFlag==0 && city_num%2==1) && cit->redwarrior->Morale>0.8) {
				show_hour();
				cout<<":40 red dragon "<<cit->redwarrior->Number<<" yelled in city "<<city_num<<endl;
			}
		}

		if (RedAward.count(city_num)>0) {
			red.lifeunit-=8;
			cit->redwarrior->Life+=8;
		}
		show_hour();
		cout<<":40 red "<<cit->redwarrior->Name<<" "<<cit->redwarrior->Number<<" earned "<<cit->CityLife<<" elements for his headquarter"<<endl;
		red.lifeunit+=cit->CityLife;
		cit->CityLife=0;

		if (cit->FightRecord<=0) cit->FightRecord=1;
		else if (cit->FightRecord>=1 && cit->CityFlag!=1) {
			cit->CityFlag=1;
			show_hour();
			cout<<":40 red flag raised in city "<<city_num<<endl;
		}
		delete cit->tempblue; cit->tempblue=NULL;
	}

	else if (cit->bluewarrior && cit->tempred) {
		if (cit->bluewarrior->Name=="wolf") capture(cit->bluewarrior, cit->tempred);
		else if (cit->bluewarrior->Name=="dragon") {
			cit->bluewarrior->Morale+=0.2;
			if ( (cit->CityFlag==-1 || cit->CityFlag==0 && city_num%2==0) && cit->bluewarrior->Morale>0.8) {
				show_hour();
				cout<<":40 blue dragon "<<cit->bluewarrior->Number<<" yelled in city "<<city_num<<endl;
			}
		}

		if (BlueAward.count(city_num)>0) {
			blue.lifeunit-=8;
			cit->bluewarrior->Life+=8;
		}
		show_hour();
		cout<<":40 blue "<<cit->bluewarrior->Name<<" "<<cit->bluewarrior->Number<<" earned "<<cit->CityLife<<" elements for his headquarter"<<endl;
		blue.lifeunit+=cit->CityLife;
		cit->CityLife=0;

		if (cit->FightRecord>=0) cit->FightRecord=-1;
		else if (cit->FightRecord<=-1 && cit->CityFlag!=-1) {
			cit->CityFlag=-1;
			show_hour();
			cout<<":40 blue flag raised in city "<<city_num<<endl;
		}
		delete cit->tempred; cit->tempred=NULL;
	}

	else if (cit->bluewarrior && cit->redwarrior) {
		warrior *winner=NULL, *loser=NULL;
		int blueLf=cit->bluewarrior->Life, redLf=cit->redwarrior->Life;
		int result=0; //+1 means red win, -1 means blue win, 0 means a tie
		if (cit->CityFlag==1 || cit->CityFlag==0&&city_num%2==1) {    //red first
		    show_hour();
		    cout<<":40 red "<<cit->redwarrior->Name<<" "<<cit->redwarrior->Number<<" attacked blue "<<
			    cit->bluewarrior->Name<<" "<<cit->bluewarrior->Number<<" in city "<<city_num<<" with "<<cit->redwarrior->Life
				<<" elements and force "<<cit->redwarrior->Attack<<endl;
			cit->bluewarrior->Life-=cit->redwarrior->Attack;
			if (cit->redwarrior->weapons.Weap[0]) {
				cit->bluewarrior->Life-=cit->redwarrior->weapons.SwordForce;
				cit->redwarrior->weapons.SwordForce*=0.8;
				if (cit->redwarrior->weapons.SwordForce==0) cit->redwarrior->weapons.Weap[0]=0;
			}
			if (cit->bluewarrior->Life<=0) {
			    result=1;
			    winner=cit->redwarrior; loser=cit->bluewarrior;
			    show_hour();
			    cout<<":40 blue "<<loser->Name<<" "<<loser->Number<<" was killed in city "<<city_num<<endl;
			}
			else {
				if (cit->bluewarrior->Name!="ninja") {
					show_hour();
					cout<<":40 blue "<<cit->bluewarrior->Name<<" "<<cit->bluewarrior->Number<<" fought back against red "<<
					    cit->redwarrior->Name<<" "<<cit->redwarrior->Number<<" in city "<<city_num<<endl;
					cit->redwarrior->Life-=(cit->bluewarrior->Attack/2);
					if (cit->bluewarrior->weapons.Weap[0]) {
						cit->redwarrior->Life-=cit->bluewarrior->weapons.SwordForce;
						cit->bluewarrior->weapons.SwordForce*=0.8;
						if (cit->bluewarrior->weapons.SwordForce==0) cit->bluewarrior->weapons.Weap[0]=0;
					}
					if (cit->redwarrior->Life<=0) {
						result=-1;
						winner=cit->bluewarrior; loser=cit->redwarrior;
						show_hour();
			    		cout<<":40 red "<<loser->Name<<" "<<loser->Number<<" was killed in city "<<city_num<<endl;
					}
				}
			}
		}
		else { //blue first
		    show_hour();
		    cout<<":40 blue "<<cit->bluewarrior->Name<<" "<<cit->bluewarrior->Number<<" attacked red "<<
			    cit->redwarrior->Name<<" "<<cit->redwarrior->Number<<" in city "<<city_num<<" with "<<cit->bluewarrior->Life
				<<" elements and force "<<cit->bluewarrior->Attack<<endl;
			cit->redwarrior->Life-=cit->bluewarrior->Attack;
			if (cit->bluewarrior->weapons.Weap[0]) {
				cit->redwarrior->Life-=cit->bluewarrior->weapons.SwordForce;
				cit->bluewarrior->weapons.SwordForce*=0.8;
				if (cit->bluewarrior->weapons.SwordForce==0) cit->bluewarrior->weapons.Weap[0]=0;
			}
			if (cit->redwarrior->Life<=0) {
			    result=-1;
			    winner=cit->bluewarrior; loser=cit->redwarrior;
			    show_hour();
			    cout<<":40 red "<<loser->Name<<" "<<loser->Number<<" was killed in city "<<city_num<<endl;
			}
			else {
				if (cit->redwarrior->Name!="ninja") {
					show_hour();
					cout<<":40 red "<<cit->redwarrior->Name<<" "<<cit->redwarrior->Number<<" fought back against blue "<<
					    cit->bluewarrior->Name<<" "<<cit->bluewarrior->Number<<" in city "<<city_num<<endl;
					cit->bluewarrior->Life-=(cit->redwarrior->Attack/2);
					if (cit->redwarrior->weapons.Weap[0]) {
						cit->bluewarrior->Life-=cit->redwarrior->weapons.SwordForce;
						cit->redwarrior->weapons.SwordForce*=0.8;
						if (cit->redwarrior->weapons.SwordForce==0) cit->redwarrior->weapons.Weap[0]=0;
					}
					if (cit->bluewarrior->Life<=0) {
						result=1;
						winner=cit->redwarrior; loser=cit->bluewarrior;
						show_hour();
			    		cout<<":40 blue "<<loser->Name<<" "<<loser->Number<<" was killed in city "<<city_num<<endl;
					}
				}
			}
		}
		//lion's initial life
		if (result!=0 && loser->Name=="lion") {
			if (loser->Head=="red") winner->Life+=redLf;
			else winner->Life+=blueLf;
		}
		//lion's loyalty decrease
		if (result==0) {
			if (cit->bluewarrior->Name=="lion") cit->bluewarrior->Loyalty-=LoyaltyDecrease;
			if (cit->redwarrior->Name=="lion") cit->redwarrior->Loyalty-=LoyaltyDecrease;
		}
		//wolf capture
		if (result!=0 && winner->Name=="wolf") capture(winner, loser);
		//dragon morale & yell
		if (result!=0&&winner->Name=="dragon") winner->Morale+=0.2;
		else if (result==0) {
			if (cit->redwarrior->Name=="dragon") cit->redwarrior->Morale-=0.2;
			if (cit->bluewarrior->Name=="dragon") cit->bluewarrior->Morale-=0.2;
		}
		if (cit->redwarrior->Name=="dragon" && cit->redwarrior->Life>0 && (cit->CityFlag==1||cit->CityFlag==0&&city_num%2==1)) {
			if (cit->redwarrior->Morale>0.8) {
				show_hour();
			    cout<<":40 red dragon "<<cit->redwarrior->Number<<" yelled in city "<<city_num<<endl;
			}
		}
		else if (cit->bluewarrior->Name=="dragon" && cit->bluewarrior->Life>0 && (cit->CityFlag==-1||cit->CityFlag==0&&city_num%2==0)) {
			if (cit->bluewarrior->Morale>0.8) {
				show_hour();
			    cout<<":40 blue dragon "<<cit->bluewarrior->Number<<" yelled in city "<<city_num<<endl;
			}
		}
		//winner get reward
		if (result!=0) {
			if (winner->Head=="red") {
				if (RedAward.count(city_num)>0) {
					winner->Life+=8;
					red.lifeunit-=8;
				}
			}
			else {
				if (BlueAward.count(city_num)>0) {
					winner->Life+=8;
					blue.lifeunit-=8;
				}
			}
		}
		//headquarter get lifeunit
		if (result!=0) {
			if (winner->Head=="red") {
				show_hour();
				cout<<":40 red "<<winner->Name<<" "<<winner->Number<<" earned "<<cit->CityLife<<" elements for his headquarter"<<endl;
				red.lifeunit+=cit->CityLife;
				cit->CityLife=0;
			}
			else {
				show_hour();
				cout<<":40 blue "<<winner->Name<<" "<<winner->Number<<" earned "<<cit->CityLife<<" elements for his headquarter"<<endl;
				blue.lifeunit+=cit->CityLife;
				cit->CityLife=0;
			}
		}
		//flag
		if (result==0) cit->FightRecord=0;
		else if (result==1) {
			if (cit->FightRecord<=0) cit->FightRecord=1;
		    else if (cit->FightRecord>=1 && cit->CityFlag!=1) {
			cit->CityFlag=1;
			show_hour();
			cout<<":40 red flag raised in city "<<city_num<<endl;
		    }
		}
		else {
			if (cit->FightRecord>=0) cit->FightRecord=-1;
		    else if (cit->FightRecord<=-1 && cit->CityFlag!=-1) {
			cit->CityFlag=-1;
			show_hour();
			cout<<":40 blue flag raised in city "<<city_num<<endl;
		    }
		}
		//delete loser
		if (result!=0) {
			if (loser->Head=="red") cit->redwarrior=NULL;
			else cit->bluewarrior=NULL;
			delete loser;
		}
	}
}

//headquarter announce
void headAnnounce (Headquarter &red, Headquarter &blue) {
	show_hour();
	cout<<":50 "<<red.lifeunit<<" elements in red headquarter"<<endl;
	show_hour();
	cout<<":50 "<<blue.lifeunit<<" elements in blue headquarter"<<endl;
}

//warrior announce
void warriorAnnounce(warrior* warr) {
    if (warr->weapons.SwordForce==0) warr->weapons.Weap[0]=0;
	show_hour();
	cout<<":55 "<<warr->Head<<" "<<warr->Name<<" "<<warr->Number<<" has ";
	if (warr->weapons.Weap[0]==0&&warr->weapons.Weap[1]==0&&warr->weapons.Weap[2]==0) cout<<"no weapon"<<endl;
	else {
		int counter=warr->weapons.Weap[0]+warr->weapons.Weap[1]+warr->weapons.Weap[2];
		int count0=0;
		if (warr->weapons.Weap[2]) {
			count0++;
			cout<<"arrow("<<warr->weapons.ArrowNum<<")";
			if (count0!=counter) cout<<",";
			else cout<<endl;
		}
		if (warr->weapons.Weap[1]) {
			count0++;
			cout<<"bomb";
			if (count0!=counter) cout<<",";
			else cout<<endl;
		}
		if (warr->weapons.Weap[0]) {
			count0++;
			cout<<"sword("<<warr->weapons.SwordForce<<")";
			cout<<endl;
		}
	}
}

//main
int main () {
	#ifdef LOCAL
	    freopen("final-in.txt","r",stdin);
	    freopen("test-out.txt","w",stdout);
	#endif
	int TestNumber;
	cin>>TestNumber;
	for (int cas=1; cas<=TestNumber; ++cas) {
		Hour=0;
		MainFlag=1;
		int headLife, cityNumber, maxHour;
		cin >> headLife >> cityNumber >> ArrowForce >> LoyaltyDecrease >> maxHour;
		for (int i=1; i<=5; i++) cin>>ini_life[i];
		for (int i=1; i<=5; i++) cin>>AttackForce[i];

		Headquarter red("red", headLife, red_ord), blue("blue", headLife, blue_ord);
		City* cities=new City [cityNumber+4];
		for (int i=0; i<cityNumber+4; ++i) {
			cities[i].CityName=n_to_s(i-1);
		}
		cities[1].isHead=1;
		cities[cityNumber+2].isHead=1;     //initialize and construct

		cout<<"Case "<<cas<<":"<<endl;
		while ((Hour)*60<=maxHour) {
			producing(cities[1].redwarrior, red);
			producing(cities[cityNumber+2].bluewarrior, blue);

			if ((Hour)*60+5<=maxHour) {
				for (int i=1; i<=cityNumber+2; ++i) {
					if (i!=cityNumber+2&&cities[i].redwarrior&&cities[i].redwarrior->LionEscape()) {
						delete cities[i].redwarrior;
						cities[i].redwarrior=NULL;
					}
					if (i!=1&&cities[i].bluewarrior&&cities[i].bluewarrior->LionEscape()) {
						delete cities[i].bluewarrior;
						cities[i].bluewarrior=NULL;
					}
				}
			}
			if ((Hour)*60+10<=maxHour) {
				allWarriorMove(cities, 1, cityNumber+2);
				for (int i=1; i<=cityNumber+2; ++i) warriorPlace(&cities[i]);
				if (!MainFlag) break;
			}
			if ((Hour)*60+20<=maxHour) {
				for (int i=2; i<=cityNumber+1; ++i) cities[i].CityLife+=10;
			}
			if ((Hour)*60+30<=maxHour) {
				for (int i=2; i<=cityNumber+1; ++i) getElement(&cities[i],red,blue);
			}
			if ((Hour)*60+35<=maxHour) {
				for (int i=2; i<=cityNumber+1; ++i) shot(&cities[i], &cities[i-1], &cities[i+1]);
				for (int i=2; i<=cityNumber+1; ++i) Arr_Kill_move(&cities[i]);
			}
			if ((Hour)*60+38<=maxHour) {
				for (int i=2; i<=cityNumber+1; ++i) bomb_using(&cities[i], i-1);
			}
			if ((Hour)*60+40<=maxHour) {
				Award_Cal(cities,cityNumber,red.lifeunit,blue.lifeunit);
			}
			if ((Hour)*60+40<=maxHour) {
				for (int i=2; i<=cityNumber+1; ++i) battling(&cities[i],i-1,red,blue);
			}
			if ((Hour)*60+50<=maxHour)
				headAnnounce(red,blue);
			if ((Hour)*60+55<=maxHour) {
				for (int i=1; i<=cityNumber+2; ++i) if (cities[i].redwarrior) warriorAnnounce(cities[i].redwarrior);
				for (int i=1; i<=cityNumber+2; ++i) if (cities[i].bluewarrior) warriorAnnounce(cities[i].bluewarrior);
			}
			Hour++;

		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值