魔兽世界 - PKU[课程作业]程序设计与算法(三)C++面向对象程序设计/coursera C++程序设计

感觉写得挺差;代码纯原创,没有半点参考;
以后若有空打算看看老师的代码,再来修改此文,先多花点时间再别的上面
建议:
1. 耐心点,仔细理解题意
2. 做到后面, 前面若有设计得不好的地方,别犹豫,赶快改吧,改完了才知道甜头
3.  以下 reference: https://blog.csdn.net/ckcz123/article/details/8734954
    如果你是直接从装备跳到终极版的话,建议你先去做一做行军
    传送门:http://poj.org/problem?id=3760
    难度较小。
4. 同样 reference: https://blog.csdn.net/ckcz123/article/details/8734954
    第三,如果你总是总是WA的话,给你一个方法。
    去下一个UltraCompare软件,
    下载地址 ------> http://www.huacolor.com/soft/69625.html
    这个东西可以将两个文本文档进行比较。
    将你的所有输出保存在一个txt文件中 (fprintf总会吧)
    然后复制下面我AC的代码,也保存在一个文件中,直接相比较,就能找到问题在哪。
    多试几组数据,随便输入,找个几次一定可以找到问题所在。

感想:
第一次写这么长的程序,也算是一种体验。
写备战还是很快,一个晚上就立刻搞定;
装备稍微麻烦一点,由于备战的类的设计不太好,改半天;
最痛苦的还是修订版,折腾了一个下午晚上外加熬夜才写完,debug总共加起来也快一天了,仔细读题也没懂,硬是对着测试数据和正确输出结果才理解题意;
终极版有了修订版的折磨,也就不足为道......

注意:
修订版和终极版也有不同
1. wolf少了“ 在一个 wolf 通过主动攻击杀死敌人的次数达到偶数的时刻(次数从1开始算),在战斗完成后,该 wolf 生命值和攻击力都增加1倍。如果其杀死的敌人是lion,则攻击力和生命值先加倍,然后才吸取lion的生命值。获取总部的生命元奖励,发生在加倍之后。只有在主动攻击杀死敌人时才能有加倍的事情,反击杀死敌人则不不会发生加倍。”的特性
2. case的输出格式......
3. 升旗方面感觉也不同,可能是修订版测试数据还弱了点??
修订版中我的理解:

【假设一】
情形一:
Flag = -1, cnt = 2 -> Flag = red, cnt = 0(red刚连胜两轮,插上旗帜)
...
Flag = red, cnt = -1(blue胜)
Flag = red, cnt = -2 -> Flag = -1, cnt = 0(blue连胜两轮)
...
Flag = -1, cnt = -1(blue胜)
Flag = -1, cnt = -2 -> Flag = blue, cnt = 0(blue连胜两轮)
情形二:
Flag = -1, cnt = 2 -> Flag = red, cnt = 0(red刚连胜两轮,插上旗帜)
...
Flag = red, cnt = -1(blue胜)
Flag = red, cnt = -2 -> Flag = -1, cnt = 0(blue连胜两轮)
...
Flag = -1, cnt = 1(red胜)
Flag = -1, cnt = 2 -> Flag = red, cnt = 0(red连胜两轮)
情形三:
Flag = -1, cnt = 2 -> Flag = red, cnt = 0(red刚连胜两轮,插上旗帜)
...
Flag = red, cnt = -1(blue胜)
Flag = red, cnt = 0(red胜)

在终极版中结果发现是这样的:
【假设二】
情形一:
Flag = -1, cnt = 2 -> Flag = red, cnt = 0(red刚连胜两轮,插上旗帜)
...
Flag = red, cnt = -1(blue胜)
Flag = red, cnt = -2 -> Flag = blue, cnt = 0(blue连胜两轮)
情形二:
Flag = -1, cnt = 2 -> Flag = red, cnt = 0(red刚连胜两轮,插上旗帜)
...
Flag = red, cnt = -1(blue胜)
Flag = red, cnt = 0(red胜)


不多说了,上代码

魔兽世界之一:备战
#include<iostream>
using namespace std;
enum warriors {dragon, ninja, iceman, lion, wolf, NUMwarriors};
char str_warriors[NUMwarriors][7] = {"dragon", "ninja", "iceman", "lion", "wolf"};
enum colors {red, blue, NUMcolors};
char str_colors[NUMcolors][5] = {"red", "blue"};
class Warrior{
	private:
		int Strength[NUMwarriors];
		int Number[NUMwarriors];
		int WCSeq[NUMwarriors];	// Warrior Creating Sequence
	public:
		Warrior()	// constructor
		{
			for( int i = 0; i < NUMwarriors; i++ )
				Number[i] = 0;
		}
	friend class Headquarter;
}; // 如何联系class Headquarter 与 class Warrior? 
class Headquarter{
	private:
		int Strength;
		int Number;
		Warrior W;
		int Clk;
	public:
		Headquarter(int M, int N = 0, int C = 0) : Strength(M),Number(N),Clk(C) {};	// constructor
		void SetWarrior( int nw, int sw )
		{
			W.Strength[nw] = sw;
		}
		void SetWCSeq( int nc )
		{
			switch(nc){
				case red:
					W.WCSeq[0] = iceman; W.WCSeq[1] = lion; W.WCSeq[2] = wolf; W.WCSeq[3] = ninja; W.WCSeq[4] = dragon;
					break;
				case blue:
					W.WCSeq[0] = lion; W.WCSeq[1] = dragon; W.WCSeq[2] = ninja; W.WCSeq[3] = iceman; W.WCSeq[4] = wolf;
					break;
				default:
					break;
			}
		}
		int CreateWarrior( int nc, int last_cnt )
		{
			int cnt = last_cnt;
			int w, i;	// w - which warrior, i - iterator
			for( i = 0; i < NUMwarriors; i++ ){
				w = W.WCSeq[cnt%NUMwarriors];	// which warrior
				if( Strength-W.Strength[w] >= 0 ){
					Strength -= W.Strength[w];
					break;
				}
				else
					cnt++;
			}
			if( i >= NUMwarriors ){
				printf("%03d %s headquarter stops making warriors\n", Clk, str_colors[nc]);
				Clk = 0;
				return -1;				
			}
			else{
				W.Number[w]++;
				Number++;
				printf("%03d %s %s %d born with strength %d", Clk, str_colors[nc], str_warriors[w], Number, W.Strength[w]);
				printf(",%d %s in %s headquarter\n", W.Number[w], str_warriors[w], str_colors[nc]);
				cnt++;
				Clk++;
				return cnt;
			}
		}
		void PrintInfo();//
};
int main()
{
	int ntc;	// the number of test cases
	cin >> ntc;
	for( int tc = 1; tc <= ntc; tc++ )
	{
		cout << "Case:" << tc << endl;
		int M;	// initial strength of the two headquarters
		cin >> M;
		Headquarter Red(M), Blue(M);
		for( int i = 0; i < NUMwarriors; i++ )
		{
			int sw;
			cin >> sw;
			Red.SetWarrior(i, sw); Blue.SetWarrior(i, sw);
		}
		Red.SetWCSeq(red); Blue.SetWCSeq(blue);
//		Red.PrintInfo(); Blue.PrintInfo();
		int res1, res2;
		res1 = Red.CreateWarrior(red, 0); res2 = Blue.CreateWarrior(blue, 0);
		while( res1 > 0 && res2 > 0 ){
			res1 = Red.CreateWarrior(red, res1); res2 = Blue.CreateWarrior(blue, res2);
		}
		while( res1 > 0 )
			res1 = Red.CreateWarrior(red, res1);
		while( res2 > 0 )
			res2 = Blue.CreateWarrior(blue, res2);
	}
	return 0;
}
void Headquarter::PrintInfo()//
{
	cout << "Strength=" << Strength << "," << "Number=" << Number << endl;
	for( int i = 0; i < NUMwarriors; i++ )
		cout << W.Strength[i] << ",";
	cout << endl;
	for( int i = 0; i < NUMwarriors; i++ )
		cout << str_warriors[W.WCSeq[i]] << ",";
	cout << endl;
}//
/*
[Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11
[Error] cannot convert '<brace-enclosed initializer list>' to 'int' in assignment
-- Arrays can only be initialized like that on definition, you can't do it afterwards.
Either move the initialization to the definition, or initialize each entry manually.
*/

魔兽世界之二:装备
#include<iostream>
using namespace std;
enum warriors {dragon, ninja, iceman, lion, wolf, NUMwarriors};
char str_warriors[NUMwarriors][7] = {"dragon", "ninja", "iceman", "lion", "wolf"};
enum weapons {sword, bomb, arrow, NUMweapons};
char str_weapons[NUMweapons][6] = {"sword", "bomb", "arrow"};
enum colors {red, blue, NUMcolors};
char str_colors[NUMcolors][5] = {"red", "blue"};
int WCSeq[NUMcolors][NUMwarriors] = { {iceman,lion,wolf,ninja,dragon}, 
   /*Warrior Creating Sequence*/	  {lion,dragon,ninja,iceman,wolf} };
/* Headquarter与Warrior - 复合关系,Warrior与具体种类 - 继承关系 */
/*可以声明一个类而不定义它 --> 前向声明(forward declaration) --> 不完全类型(incompete type)
  只能以有限方式使用,不能定义该类型的对象,只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数*/
class Headquarter;
class Warrior{
	private:
		int Strength;
		int Number;
		int Attribute;
		Headquarter *H;
	public:
		Warrior( int a, int s, int N, Headquarter *h )	// constructor
		{
			Attribute = a; Strength = s; Number = N; H = h;
		}
};
class Dragon: public Warrior{
	private:
		int Weapon;
		double Morale;
	public:
		Dragon( int n, int S, int a, int s, int N, Headquarter *h ): Warrior(a,s,N,h)	// constructor
		{
			Weapon = n%3; Morale = (double)S/s;
			Dragon::AdditionalProperties();
		}
		void AdditionalProperties(){
			printf("It has a %s,and it's morale is %.2lf\n", str_weapons[Weapon], Morale);
		}
};
class Ninja: public Warrior{
	private:
		int Weapon[2];
	public:
		Ninja( int n, int a, int s, int N, Headquarter *h ): Warrior(a,s,N,h)	// constructor
		{
			Weapon[0] = n%3; Weapon[1] = (n+1)%3;
			Ninja::AdditionalProperties();
		}
		void AdditionalProperties(){
			printf("It has a %s and a %s\n", str_weapons[Weapon[0]], str_weapons[Weapon[1]]);
		}
};
class Iceman: public Warrior{
	private:
		int Weapon;
	public:
		Iceman( int n, int a, int s, int N, Headquarter *h ): Warrior(a,s,N,h)	// constructor
		{
			Weapon = n%3;
			Iceman::AdditionalProperties();
		}
		void AdditionalProperties(){
			printf("It has a %s\n", str_weapons[Weapon]);
		}
};
class Lion: public Warrior{
	private:
		int Loyalty;
	public:
		Lion( int n, int S, int a, int s, int N, Headquarter *h ): Warrior(a,s,N,h)	// constructor
		{
			Loyalty = S;
			Lion::AdditionalProperties();
		}
		void AdditionalProperties(){
			printf("It's loyalty is %d\n", Loyalty);
		}
};
class Headquarter{
	private:
		int Strength;
		int SW[NUMwarriors];	// Strength of Warriors
		int NW[NUMwarriors];	// Number of Warriors
		int Number;	// Number of Warriors in Total
		int Color;
		Warrior *W[10000];
		int Clk;
	public:
		Headquarter( int M, int nc, int sw[], int N = 0, int C = 0 )	// constructor
		{
			Strength = M; Color = nc; Number = N; Clk = C;
			for( int i = 0; i < NUMwarriors; i++ ){
				SW[i] = sw[i]; NW[i] = 0;				
			}
		}
		int CreateWarrior( int last_cnt )
		{
			int cnt = last_cnt;
			int a, i;	// a - which warrior, i - iterator
			for( i = 0; i < NUMwarriors; i++ ){
				a = WCSeq[Color][cnt%NUMwarriors];	// which warrior
				if( Strength-SW[a] >= 0 ){
					Strength -= SW[a];
					break;
				}
				else
					cnt++;
			}
			if( i >= NUMwarriors ){
				printf("%03d %s headquarter stops making warriors\n", Clk, str_colors[Color]);
				Clk = 0;
				return -1;
			}
			else{
				Number++; NW[a]++;
				printf("%03d %s %s %d born with strength %d", Clk, str_colors[Color], str_warriors[a], Number, SW[a]);
				printf(",%d %s in %s headquarter\n", NW[a], str_warriors[a], str_colors[Color]);
				switch(a){
					case dragon: W[Number] = new Dragon(Number, Strength, dragon, SW[dragon], NW[dragon], this); break;
					case ninja: W[Number] = new Ninja(Number, ninja, SW[ninja], NW[ninja], this); break;
					case iceman: W[Number] = new Iceman(Number, iceman, SW[iceman], NW[iceman], this); break;
					case lion: W[Number] = new Lion(Number, Strength, lion, SW[lion], NW[lion], this); break;
					case wolf: W[Number] = new Warrior(wolf, SW[wolf], NW[wolf], this); break;
					default: break;
				}
				cnt++; Clk++;
				return cnt;
			}
		}
		void PrintInfo();// 
};
int main()
{
	int ntc; cin >> ntc;	// number of test cases
	for( int tc = 1; tc <= ntc; tc++ )
	{
		int M; cin >> M;	// initial strength of the two headquarters
		int sw[NUMwarriors];	// strength of warriors
		for( int i = 0; i < NUMwarriors; i++ )
			cin >> sw[i];
		cout << "Case:" << tc << endl;
		Headquarter Red(M, red, sw), Blue(M, blue, sw);
//		Red.PrintInfo(); Blue.PrintInfo();
		int res1, res2;
		res1 = Red.CreateWarrior(0); res2 = Blue.CreateWarrior(0);
		while( res1 > 0 && res2 > 0 ){
			res1 = Red.CreateWarrior(res1); res2 = Blue.CreateWarrior(res2);
		}
		while( res1 > 0 )
			res1 = Red.CreateWarrior(res1);
		while( res2 > 0 )
			res2 = Blue.CreateWarrior(res2);
	}
	return 0;
}
void Headquarter::PrintInfo()//
{
	cout << "Strength=" << Strength << "," << "Number=" << Number << endl;
	for( int i = 0; i < NUMwarriors; i++ )
		cout << SW[i] << ",";
	cout << endl;
	for( int i = 0; i < NUMwarriors; i++ )
		cout << str_warriors[WCSeq[Color][i]] << ",";
	cout << endl;
}//

魔兽世界(修订版)
http://poj.org/problem?id=3760
POJ上面的一道题,如果直接写终极版可能会难度很大,可以先尝试这道题
#include<iostream>
using namespace std;
#define MAX 100000

enum warriors {dragon, ninja, iceman, lion, wolf, NUMwarriors};
char str_warriors[NUMwarriors][7] = {"dragon", "ninja", "iceman", "lion", "wolf"};
enum colors {red, blue, NUMcolors};
char str_colors[NUMcolors][5] = {"red", "blue"};
int WCSeq[NUMcolors][NUMwarriors] = { {iceman,lion,wolf,ninja,dragon},
   /*Warrior Creating Sequence*/	  {lion,dragon,ninja,iceman,wolf} };
int N;	// Number of Cities
int Clk;
bool WarEnd;

class Headquarter;
class Warrior{
	protected:	// not private, otherwise class derived cannot visit
		int Attribute, Color;
		int Strength, Number, Attack;
		int Location, Distance;
		Headquarter *H;
	public:
		Warrior( int a, int cn, int s, int n, int atk, Headquarter *h )	// constructor
		{
			Attribute = a; Color = cn; H = h;
			Strength = s; Number = n; Attack = atk;
			switch(Color)
			{
				case red: Location = -1; break;
				case blue: Location = N; break;
				default: break;
			}
		}
		int GetAttribute() { return Attribute; }
		int GetColor() { return Color; }
		int GetStrength() { return Strength; }
		int GetNumber() { return Number; }
		int GetAttack() { return Attack; }
		void NextStep()
		{
			switch(Color)
			{
				case red: Location++; break;
				case blue: Location--; break;
				default: break;
			}
		}
		int GetLocation() { return Location; }
		Headquarter *BringBackStrength( int s ) { return H; }
		void ReceiveStrength( int s ) { Strength += s; }
		void GetAward() { Strength += 8; }
		virtual bool StartAttack( Warrior *p )	// false - enemy died, true - enemy alive
		{	// [NOTE] battle lion-er,lion-ee
			if( Attribute == lion ) SetPS();
			if( p->GetAttribute() == lion ) p->SetPS();
			p->Strength -= Attack;
			if( p->Strength < 0 )
				p->Strength = 0;
			return p->Strength;
		}
		virtual bool FightBack( Warrior *p )	// false - enemy died, true - enemy alive
		{
			p->Strength -= Attack/2;
			if( p->Strength < 0 )
				p->Strength = 0;
			return p->Strength;
		}
		// polymorphism for class Iceman
		virtual void Proceed() {}
		// polymorphism for class Lion
		virtual void StrengthTransfer( Warrior *p ) {}
		virtual void SetPS() {}
		virtual int GetPS() {}
		// polymorphism for class Wolf
		virtual void Kill() {}
};
class Dragon: public Warrior{
	public:
		Dragon( int a, int cn, int s, int n, int atk, Headquarter *h ): Warrior(a,cn,s,n,atk,h) {}
};
class Ninja: public Warrior{
	public:
		Ninja( int a, int cn, int s, int n, int atk, Headquarter *h ): Warrior(a,cn,s,n,atk,h) {}
		virtual bool FightBack( Warrior *p )	// false - enemy died, true - enemy alive
		{
			return true;
		}
};
class Iceman: public Warrior{
	private:
		int steps;
	public:
		Iceman( int a, int cn, int s, int n, int atk, Headquarter *h ): Warrior(a,cn,s,n,atk,h) {
			steps = 0;
		}
		virtual void Proceed(){	// true - dec strength and inc attack, false - do nothing
			if( (++steps) % 2 == 0 ){
				Strength -= 9;
				if( Strength <= 0 ) Strength = 1;
				Attack += 20;
			}
		}
};
class Lion: public Warrior{
	private:
		int PS;	// Previous Strength
	public:
		Lion( int a, int cn, int s, int n, int atk, Headquarter *h ): Warrior(a,cn,s,n,atk,h) {}
		virtual void SetPS() { PS = Strength; }
		virtual int GetPS() { return PS; }
};
class Wolf: public Warrior{
	private:
		int kill;
	public:
		Wolf( int a, int cn, int s, int n, int atk, Headquarter *h ): Warrior(a,cn,s,n,atk,h) { kill = 0; }
		virtual void Kill() {
			if( (++kill) % 2 == 0 ){
				Strength <<= 1; Attack <<= 1;
			}
		}
};

class City;
class Headquarter{
	private:
		int Strength;
		int Color;
		int SW[NUMwarriors];	// Strength of Warriors
		int AW[NUMwarriors];	// Attack of Warriors
		int NW[NUMwarriors];	// Number of Warriors
		int Number;	// Number of Warriors in Total
		Warrior *W[MAX];	//指针数组
		Warrior *E[2];	// Enemies 
	public:
		Headquarter( int M, int nc, int sw[], int atk[], int N = 0 )	// constructor
		{
			Strength = M; Color = nc; Number = N;
			for( int i = 0; i < NUMwarriors; i++ ){
				SW[i] = sw[i]; NW[i] = 0; AW[i] = atk[i];
			}
			for( int i = 0; i < MAX; i++ )
				W[i] = NULL;
			E[0] = NULL; E[1] = NULL;
		}
		~Headquarter()
		{
			for( int i = 0; W[i]; i++ )
				delete W[i];
		}
		int CreateWarrior( int last_cnt );
		void Report() {
			printf("%03d:50 %d elements in %s headquarter\n", Clk/60, Strength, str_colors[Color]);
		}
		int GetColor() { return Color; }
		void GiveAward( Warrior *p )
		{
			if( Strength-8 >= 0 ){
				Strength -= 8;
				p->GetAward();
			}
		}
		void ReceiveStrength( int s ) { Strength += s; }
		void PrintInfo();
	friend void Marching( Headquarter *Red, Headquarter *Blue, City **C );
	friend void Battle( Headquarter *Red, Headquarter *Blue, City **C );
}; 
int Headquarter::CreateWarrior( int last_cnt )
{
	int cnt = last_cnt;
	int a;	// a - which warrior
	a = WCSeq[Color][cnt%NUMwarriors];	// which warrior
	if( Strength-SW[a] >= 0 ){
		Strength -= SW[a];
		Number++; NW[a]++;
		switch(a){	//Warrior( int a, int cn, int s, int n, int atk )	// constructor
			case dragon:
				W[Number-1] = new Dragon(dragon,Color,SW[a],Number,AW[a],this);
				break;
			case ninja:
				W[Number-1] = new Ninja(ninja,Color,SW[a],Number,AW[a],this);
				break;
			case iceman:
				W[Number-1] = new Iceman(iceman,Color,SW[a],Number,AW[a],this);
				break;
			case lion:
				W[Number-1] = new Lion(lion,Color,SW[a],Number,AW[a],this);
				break;
			case wolf:
				W[Number-1] = new Wolf(wolf,Color,SW[a],Number,AW[a],this);
				break;
			default:
				break;
		}
		printf("%03d:00 %s %s %d born\n", Clk/60, str_colors[Color], str_warriors[a], Number);
		cnt++;
	}
	return cnt;
}

class City{
	private:
		int Number, Strength;	// Number: 0~N-1 - 1~N
		int Flag, cnt;
		Warrior *w[2];	// Warriors in the City
	public:
		City( int num )
		{
			Number = num; Strength = 0;
			w[0] = NULL; w[1] = NULL;
			Flag = -1; cnt = 0;
		}
		void IncStrength() {
			Strength += 10;
		}
		void ClearLastRecord(){
			w[0] = NULL; w[1] = NULL;
		}
		void Test() {
			if( w[0] && !w[1] ){
				Headquarter *h = w[0]->BringBackStrength( Strength );
				h->ReceiveStrength(Strength);
				printf("%03d:30 %s %s %d ", Clk/60, str_colors[h->GetColor()], str_warriors[w[0]->GetAttribute()], w[0]->GetNumber());
				printf("earned %d elements for his headquarter\n", Strength);
				Strength = 0;
			}
		}
		Warrior *CityBattle1( Warrior *survivor );
		void CityBattle2( Warrior *survivor );
	friend void Marching( Headquarter *Red, Headquarter *Blue, City **C );
	friend void Battle( Headquarter *Red, Headquarter *Blue, City **C );
};

void Battle( Headquarter *Red, Headquarter *Blue, City **C )
{
	Warrior *survivor[N];
	for( int j = 0; j < N; j++ )
		survivor[j] = NULL;
	for( int j = 0; j < N; j++ )
		survivor[j] = C[j]->CityBattle1(survivor[j]);
	for( int i = N-1; i >= 0; i-- )
		if( survivor[i] && survivor[i]->GetColor() == red )
			Red->GiveAward(survivor[i]);
	for( int i = 0; i < N; i++ )
		if( survivor[i] && survivor[i]->GetColor() == blue )
			Blue->GiveAward(survivor[i]);
	for( int j = 0; j < N; j++ )
		C[j]->CityBattle2(survivor[j]);
}
Warrior *City::CityBattle1( Warrior *survivor )
{
	if( w[0] && w[1] ){
		Warrior *er, *ee;
		if( ( Number%2 == 0 && Flag == -1 ) || Flag == red ){// w[0] - red, w[1] - blue
			er = w[0]; ee = w[1];
		}
		else if( ( Number%2 == 1 && Flag == -1 ) || Flag == blue ){
			er = w[1]; ee = w[0];
		}
		bool alive = er->StartAttack(ee);
		printf("%03d:40 %s %s %d attacked ", Clk/60, str_colors[er->GetColor()], str_warriors[er->GetAttribute()], er->GetNumber());
		printf("%s %s %d in city %d ", str_colors[ee->GetColor()], str_warriors[ee->GetAttribute()], ee->GetNumber(), Number+1);
		printf("with %d elements and force %d\n", er->GetStrength(), er->GetAttack());
		if( alive == true ){
			alive = ee->FightBack(er);
			if( ee->GetAttribute() != ninja ){
				printf("%03d:40 %s %s %d ", Clk/60, str_colors[ee->GetColor()], str_warriors[ee->GetAttribute()], ee->GetNumber());
				printf("fought back against ");
				printf("%s %s %d in city %d\n", str_colors[er->GetColor()], str_warriors[er->GetAttribute()], er->GetNumber(), Number+1);				
			}
			if( alive == false ){
				printf("%03d:40 %s %s %d ", Clk/60, str_colors[er->GetColor()], str_warriors[er->GetAttribute()], er->GetNumber());
				printf("was killed in city %d\n", Number+1);
				if( er->GetAttribute() == lion )
					ee->ReceiveStrength(er->GetPS());
			}
		}
		else{
			printf("%03d:40 %s %s %d ", Clk/60, str_colors[ee->GetColor()], str_warriors[ee->GetAttribute()], ee->GetNumber());
			printf("was killed in city %d\n", Number+1);
			if( er->GetAttribute() == wolf )
				er->Kill();
			if( ee->GetAttribute() == lion )
				er->ReceiveStrength(ee->GetPS());
		}
		if( er->GetAttribute() == dragon && er->GetStrength() )
			printf("%03d:40 %s dragon %d yelled in city %d\n", Clk/60, str_colors[er->GetColor()], er->GetNumber(), Number+1);
		if( er->GetStrength() && !ee->GetStrength() ) survivor = er;
		else if( ee->GetStrength() && !er->GetStrength() ) survivor = ee;
		if( survivor ){
			printf("%03d:40 %s %s %d ", Clk/60, str_colors[survivor->GetColor()], str_warriors[survivor->GetAttribute()], survivor->GetNumber());
			printf("earned %d elements for his headquarter\n", Strength);
		}
		if( !survivor ){
			switch(Flag){
				case -1: cnt = 0; break;
				case red: break;
				case blue: break;
				default: break;
			}
		}
		else{
			int c = survivor->GetColor();
			switch(Flag){
				case -1:
					switch(c){
						case red:
							if( ++cnt == 2 ){
								printf("%03d:40 red flag raised in city %d\n", Clk/60, Number+1);
								Flag = red; cnt = 0;
							}
							break;
						case blue:
							if( --cnt == -2 ){
								printf("%03d:40 blue flag raised in city %d\n", Clk/60, Number+1);
								Flag = blue; cnt = 0;
							}
							break;
						default: break;
					}
					break;
				case red:
					switch(c){
						case red: break;
						case blue: Flag = -1; break;
						default: break;
					}
					break;
				case blue:
					switch(c){
						case red: Flag = -1; break;
						case blue: break;
						default: break;
					}
					break;
				default: break;
			}
		}
	}
	return survivor;
}
void City::CityBattle2( Warrior *survivor )
{
	if( survivor )
	{
		Headquarter *h = survivor->BringBackStrength( Strength );
		h->ReceiveStrength(Strength);
		Strength = 0;
	}
}

void Marching( Headquarter *Red, Headquarter *Blue, City **C )
{
	for( int i = 0; i < N; i++ )
		C[i]->ClearLastRecord();
	for( int i = 0; Red->W[i]; i++ )
	{
		if( Red->W[i]->GetStrength() == 0 )
			continue;
		Red->W[i]->NextStep();
		int l = Red->W[i]->GetLocation();
		if( l < N && l > -1 ){
			if( !C[l]->w[0] )
				C[l]->w[0] = Red->W[i];
			else if( !C[l]->w[1] )
				C[l]->w[1] = Red->W[i];
		}
		else if( l == N ){
			if( !Blue->E[0] )
				Blue->E[0] = Red->W[i];
			else if( !Blue->E[1] )
				Blue->E[1] = Red->W[i];
		}
	}
	for( int i = 0; Blue->W[i]; i++ )
	{
		if( Blue->W[i]->GetStrength() == 0 )
			continue;
		Blue->W[i]->NextStep();
		int l = Blue->W[i]->GetLocation();
		if( l == -1 ){
			if( !Red->E[0] )
				Red->E[0] = Blue->W[i];
			else if( !Red->E[1] )
				Red->E[1] = Blue->W[i];
		}
		else if( l < N && l > -1 ){
			if( !C[l]->w[0] )
				C[l]->w[0] = Blue->W[i];
			else if( !C[l]->w[1] )
				C[l]->w[1] = Blue->W[i];
		}
	}
	int last = -1;
	if( Red->E[1] ) last = 1;
	else if( Red->E[0] ) last = 0;
	if( last >= 0 && Red->E[last]->GetLocation() == -1 ){
		Warrior *w = Red->E[last];
		int a = w->GetAttribute();
		printf("%03d:10 %s %s %d ", Clk/60, str_colors[w->GetColor()], str_warriors[a], w->GetNumber());
		printf("reached red headquarter ");
		if( a == iceman ) w->Proceed();
		printf("with %d elements and force %d\n", w->GetStrength(), w->GetAttack());
		if( last == 1 ){
			printf("%03d:10 red headquarter was taken\n", Clk/60);
			WarEnd = true;
		}
	}
	for( int i = 0; i < N; i++ )
		for( int j = 0; C[i]->w[j] && j < 2; j++ )
		{
			Warrior *w = C[i]->w[j];
			int a = w->GetAttribute();
			printf("%03d:10 %s %s %d ", Clk/60, str_colors[w->GetColor()], str_warriors[a], w->GetNumber());
			printf("marched to city %d ", i+1);
			if( a == iceman ) w->Proceed();
			printf("with %d elements and force %d\n", w->GetStrength(), w->GetAttack());
		}
	last = -1;
	if( Blue->E[1] ) last = 1;
	else if( Blue->E[0] ) last = 0;
	if( last >= 0 && Blue->E[last]->GetLocation() == N ){
		Warrior *w = Blue->E[last];
		int a = w->GetAttribute();
		printf("%03d:10 %s %s %d ", Clk/60, str_colors[w->GetColor()], str_warriors[a], w->GetNumber());
		printf("reached blue headquarter ");
		if( a == iceman ) w->Proceed();
		printf("with %d elements and force %d\n", w->GetStrength(), w->GetAttack());
		if( last == 1 ){
			printf("%03d:10 blue headquarter was taken\n", Clk/60);
			WarEnd = true;
		}
	}
}

int main()
{
	int ntc; cin >> ntc;	// number of test cases
	for( int tc = 1; tc <= ntc; tc++ )
	{
		int M, T; cin >> M >> N >> T;
		// initial strength of the two headquarters; Number of Cities; Time Limit 
		int sw[NUMwarriors], atk[NUMwarriors];	// strength of warriors; attack of warriors
		for( int i = 0; i < NUMwarriors; i++ )
			cin >> sw[i];
		for( int i = 0; i < NUMwarriors; i++ )
			cin >> atk[i];
		cout << "Case:" << tc << endl;
		WarEnd = false;
		Headquarter Red(M, red, sw, atk), Blue(M, blue, sw, atk);
		City *C[N];
		for( int i = 0; i < N; i++ )
			C[i] = new City(i);
		int res1 = 0, res2 = 0;
		for( Clk = 0; Clk <= T; Clk += 10 )
		{
			if( WarEnd == true ) break;
			switch(Clk%60)
			{
				case 0:
					if( res1 >= 0 )
						res1 = Red.CreateWarrior(res1);
					if( res2 >= 0 )
						res2 = Blue.CreateWarrior(res2);
					break;
				case 10:
					Marching(&Red,&Blue,C);
					break;
				case 20:
					for( int i = 0; i < N; i++ )
						C[i]->IncStrength();
					break;
				case 30:
					for( int i = 0; i < N; i++ )
						C[i]->Test();
					break;
				case 40:
					Battle(&Red,&Blue,C);
					break;
				case 50:
					Red.Report(); Blue.Report();
					break;
				default:
					break;
			}
		}
		for( int i = 0; i < N; i++ )
			delete C[i];
	}	
	return 0;
}

魔兽世界终极版
 
 
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
#define MAX 100000

enum warriors {dragon, ninja, iceman, lion, wolf, NUMwarriors};
char str_warriors[NUMwarriors][7] = {"dragon", "ninja", "iceman", "lion", "wolf"};
enum weapons {sword, bomb, arrow, NUMweapons};
char str_weapons[NUMweapons][6] = {"sword", "bomb", "arrow"};
enum colors {red, blue, NUMcolors};
char str_colors[NUMcolors][5] = {"red", "blue"};
int WCSeq[NUMcolors][NUMwarriors] = { {iceman,lion,wolf,ninja,dragon},
   /*Warrior Creating Sequence*/	  {lion,dragon,ninja,iceman,wolf} };
int N;	// Number of Cities
int R;	// force of arrow
int K;	// decrement of Loyalty
int Clk;
bool WarEnd;

class Warrior;
class Weapon{
	protected:
		int Force;
		int Attribute;
		bool Existence;
	public:
		Weapon( int a ) { Existence = true; Attribute = a; }
		inline int GetAttribute() { return Attribute; }
		inline int GetExistence() { return Existence; }
		inline int GetForce() { return Force; }
		// polymorphism for class Sword
		virtual void dull() {}
		// polymorphism for class Arrow
		virtual void DecUse() {}
		virtual int GetUse() {}
		// polymorphism for class Bomb
		virtual void Blast() {}
};
class Sword: public Weapon{
	public:
		Sword( int a, int wf ):Weapon(a) {	// warrior's force
			Force = 0.2*wf;
			if( !Force ) Existence = false;
		}
		virtual void dull() {	// sword每经过一次战斗(不论是主动攻击还是反击),就会变钝,攻击力变为本次战斗前的80% (去尾取整)
			Force *= 0.8;
			if( !Force ) Existence = false;
		}
};
class Arrow: public Weapon{
	private:
		int Use;
	public:
		Arrow( int a ):Weapon(a) {
			Force = R; Use = 3;
		}
		virtual void DecUse() {
			if( !(--Use) ) Existence = false;
		}
		virtual int GetUse() {
			 return Use; 
		}
};
class Bomb: public Weapon{
	public:
		Bomb( int a ):Weapon(a) {}
		virtual void Blast() {
			Existence = false;
		}
};

class Headquarter;
class City;
class Warrior{
	protected:	// not private, otherwise derived classes cannot visit
		int Attribute, Color;
		int Strength, Number, Attack;
		int Location, Distance;
		Headquarter *H;
		Weapon *WP[NUMweapons];	// weapon
		bool Tag;	// true - bomb to death
	public:
		Warrior( int a, int cn, int s, int n, int atk, Headquarter *h )	// constructor
		{
			Attribute = a; Color = cn; H = h;
			Strength = s; Number = n; Attack = atk;
			switch(Color)
			{
				case red: Location = -1; break;
				case blue: Location = N; break;
				default: break;
			}
			for( int i = 0; i < NUMweapons; i++ )
				WP[i] = NULL;
			Tag = false;
		}
		~Warrior()
		{
			for( int i = 0; i < NUMweapons; i++ )
				if( WP[i] )
					delete WP[i];
		}
		virtual bool StartAttack( Warrior *p )	// start attack to p, true - p alive
		{	// [NOTE] battle lion-er,lion-ee
			if( Attribute == lion ) SetPS();
			if( p->GetAttribute() == lion ) p->SetPS();
			p->Strength -= Attack;
			if( WP[sword] != NULL )
			{
				if( !WP[sword]->GetExistence() )
					WP[sword] = NULL;
				else{
					p->Strength -= WP[sword]->GetForce();
					WP[sword]->dull();
				}
			}
			if( p->Strength < 0 )
				p->Strength = 0;
			return p->Strength;
		}
		virtual bool FightBack( Warrior *p )	// fight back to p, true - p alive
		{
			p->Strength -= Attack/2;
			if( WP[sword] != NULL )
			{
				if( !WP[sword]->GetExistence() )
					WP[sword] = NULL;
				else{
					p->Strength -= WP[sword]->GetForce();
					WP[sword]->dull();
				}
			}
			if( p->Strength < 0 )
				p->Strength = 0;
			return p->Strength;
		}
		bool judge_Start( Warrior *p )	// p start attack, true - alive
		{
			int tmpS = Strength;
			tmpS -= p->Attack;
			if( p->WP[sword] )
			{
				if( !p->WP[sword]->GetExistence() )
					p->WP[sword] = NULL;
				else
					tmpS -= p->WP[sword]->GetForce();
			}
			if( tmpS < 0 ) tmpS = 0;
			return tmpS;
		}
		bool judge_Back( Warrior *p )	// start attack, p (do not die) fight back, true - alive
		{
			if( p->judge_Start(this) == false )	// start attack, p die, no fight back
				return true;
			if( p->GetAttribute() == ninja )
				return true;
			int tmpS = Strength;
			tmpS -= p->Attack/2;
			if( p->WP[sword] != NULL )
			{
				if( !p->WP[sword]->GetExistence() )
					p->WP[sword] = NULL;
				else
					tmpS -= p->WP[sword]->GetForce();
			}
			if( tmpS < 0 ) tmpS = 0;
			return tmpS;
		}
		bool shotted( Warrior *p )	// false - the shotted died, true - the shotted alive
		{
			p->Strength -= R;
			if( p->Strength < 0 )
				p->Strength = 0;
			if( p->Attribute == lion )
				p->SetPS();	// lion 若是战死,则其战斗前的生命值就会转移到对手身上。所谓"战斗前",就是每个小时的40分前的一瞬间。
			return p->Strength;
		}
		void WeaponState();
		void CheckWeapon();
		inline int GetAttribute() { return Attribute; }
		inline int GetColor() { return Color; }
		inline int GetStrength() { return Strength; }
		inline int ClearStrength() { Strength = 0; }
		inline int GetNumber() { return Number; }
		inline int GetAttack() { return Attack; }
		inline void NextStep()
		{
			switch(Color)
			{
				case red: Location++; break;
				case blue: Location--; break;
				default: break;
			}
		}
		inline int GetLocation() { return Location; }
		inline Headquarter *BringBackStrength( int s ) { return H; }
		inline Weapon *GetWeapon( int i ) { return WP[i]; }
		inline Weapon *LoseWeapon( int i ) {
			Weapon *ret = WP[i];
			WP[i] = NULL;
			return ret;
		}
		inline void ClearWeapon( int i ) { WP[i] = NULL; }
		inline void SetTag() { Tag = true; }
		inline bool GetTag() { return Tag; }
		inline void ReceiveStrength( int s ) { Strength += s; }
		inline void GetAward() { Strength += 8; }
		// polymorphism for class Dragon
		virtual double GetMorale() {}
		virtual void IncMorale() {}
		virtual void DecMorale() {}
		// polymorphism for class Iceman
		virtual void Proceed() {}
		// polymorphism for class Lion
		virtual void StrengthTransfer( Warrior *p ) {}
		virtual void SetPS() {}
		virtual int GetPS() {}
		virtual void DecLoyalty() {}
		virtual int GetLoyalty() {}
		// polymorphism for class Wolf
		virtual void Kill() {}
		virtual void ReceiveWeapon( Warrior *p ) {}
	friend void ReleaseArrow( City **C );
};
class Dragon: public Warrior{
	private:
		double Morale;
	public:
		Dragon( int a, int cn, int s, int n, int atk, Headquarter *h, int S ): Warrior(a,cn,s,n,atk,h)
		{
			switch(Number%3)
			{
				case sword: WP[sword] = new Sword(sword,Attack); break;
				case arrow: WP[arrow] = new Arrow(arrow); break;
				case bomb: WP[bomb] = new Bomb(bomb); break;
				default: break;
			}
			Morale = (double)S/Strength;
		}
		virtual double GetMorale() { return Morale; }
		virtual void IncMorale() { Morale += 0.2; }
		virtual void DecMorale() { Morale -= 0.2; }
};
class Ninja: public Warrior{
	public:
		Ninja( int a, int cn, int s, int n, int atk, Headquarter *h ): Warrior(a,cn,s,n,atk,h)
		{
			for( int i = 0; i < 2; i++ )
				switch( (Number+i)%3 )
				{
					case sword: WP[sword] = new Sword(sword,Attack); break;
					case arrow: WP[arrow] = new Arrow(arrow); break;
					case bomb: WP[bomb] = new Bomb(bomb); break;
					default: break;
				}
		}
		virtual bool FightBack( Warrior *p )	// fight back to p, true - p alive
		{
			return true;
		}
};
class Iceman: public Warrior{
	private:
		int steps;
	public:
		Iceman( int a, int cn, int s, int n, int atk, Headquarter *h ): Warrior(a,cn,s,n,atk,h)
		{
			steps = 0;
			switch(Number%3)
			{
				case sword: WP[sword] = new Sword(sword,Attack); break;
				case arrow: WP[arrow] = new Arrow(arrow); break;
				case bomb: WP[bomb] = new Bomb(bomb); break;
				default: break;
			}
		}
		virtual void Proceed(){	// true - dec strength and inc attack, false - do nothing
			if( (++steps) % 2 == 0 ){
				Strength -= 9;
				if( Strength <= 0 ) Strength = 1;
				Attack += 20;
			}
		}
};
class Lion: public Warrior{
	private:
		int Loyalty;
		int PS;	// Previous Strength
	public:
		Lion( int a, int cn, int s, int n, int atk, Headquarter *h, int S ): Warrior(a,cn,s,n,atk,h)
		{
			Loyalty = S;
		}
		virtual void SetPS() { PS = Strength; }
		virtual int GetPS() { return PS; }
		virtual void DecLoyalty() {
			Loyalty -= K;
			if( Loyalty < 0 )
				Loyalty = 0;
		}
		virtual int GetLoyalty() { return Loyalty; }
};
class Wolf: public Warrior{
	private:
		int kill;
	public:
		Wolf( int a, int cn, int s, int n, int atk, Headquarter *h ): Warrior(a,cn,s,n,atk,h) { kill = 0; }
		virtual void Kill() {
			if( (++kill) % 2 == 0 ){
				Strength <<= 1; Attack <<= 1;
			}
		}
		virtual void ReceiveWeapon( Warrior *p );
};
void Wolf::ReceiveWeapon( Warrior *p )
{
	for( int i = 0; i < NUMweapons; i++ )
		if( WP[i] == NULL )
			WP[i] = p->LoseWeapon(i);
}

class City;
class Headquarter{
	private:
		int Strength;
		int Color;
		int SW[NUMwarriors];	// Strength of Warriors
		int AW[NUMwarriors];	// Attack of Warriors
		int NW[NUMwarriors];	// Number of Warriors
		int Number;	// Number of Warriors in Total
		Warrior *W[MAX];	//指针数组
		Warrior *E[2];	// Enemies
	public:
		Headquarter( int M, int nc, int sw[], int atk[], int N = 0 )	// constructor
		{
			Strength = M; Color = nc; Number = N;
			for( int i = 0; i < NUMwarriors; i++ ){
				SW[i] = sw[i]; NW[i] = 0; AW[i] = atk[i];
			}
			for( int i = 0; i < MAX; i++ )
				W[i] = NULL;
			E[0] = NULL; E[1] = NULL;
		}
		~Headquarter()
		{
			for( int i = 0; W[i]; i++ )
				delete W[i];
		}
		int CreateWarrior( int last_cnt );
		void RunAway();
		inline void Report() {
			printf("%03d:50 %d elements in %s headquarter\n", Clk/60, Strength, str_colors[Color]);
		}
		inline int GetColor() { return Color; }
		inline void GiveAward( Warrior *p )
		{
			if( Strength-8 >= 0 ){
				Strength -= 8;
				p->GetAward();
			}
		}
		inline void ReceiveStrength( int s ) { Strength += s; }
	friend void Marching( Headquarter *Red, Headquarter *Blue, City **C );
	friend void Battle( Headquarter *Red, Headquarter *Blue, City **C );
	friend void ReportWeapon( Headquarter *Red, Headquarter *Blue, City **C );
}; 
int Headquarter::CreateWarrior( int last_cnt )
{
	int cnt = last_cnt;
	int a;	// a - which warrior
	a = WCSeq[Color][cnt%NUMwarriors];	// which warrior
	if( Strength-SW[a] >= 0 ){
		Strength -= SW[a];
		Number++; NW[a]++;
		printf("%03d:00 %s %s %d born\n", Clk/60, str_colors[Color], str_warriors[a], Number);
		switch(a){	//Warrior( int a, int cn, int s, int n, int atk )	// constructor
			case dragon:
				W[Number-1] = new Dragon(dragon,Color,SW[a],Number,AW[a],this,Strength);
				printf("Its morale is %.2lf\n", W[Number-1]->GetMorale());
				break;
			case ninja:
				W[Number-1] = new Ninja(ninja,Color,SW[a],Number,AW[a],this);
				break;
			case iceman:
				W[Number-1] = new Iceman(iceman,Color,SW[a],Number,AW[a],this);
				break;
			case lion:
				W[Number-1] = new Lion(lion,Color,SW[a],Number,AW[a],this,Strength);
				printf("Its loyalty is %d\n", W[Number-1]->GetLoyalty());
				break;
			case wolf:
				W[Number-1] = new Wolf(wolf,Color,SW[a],Number,AW[a],this);
				break;
			default:
				break;
		}
		cnt++;
	}
	return cnt;
}
void Headquarter::RunAway()
{
	for( int i = 0; i < Number; i++ )
		if( W[i]->GetAttribute() == lion && !W[i]->GetLoyalty() && W[i]->GetStrength() )
		{
			W[i]->ClearStrength();
			printf("%03d:05 %s lion %d ran away\n", Clk/60, str_colors[W[i]->GetColor()], W[i]->GetNumber());		
		}
}

class City{
	private:
		int Number, Strength;	// Number: 0~N-1 - 1~N
		int Flag, cnt;
		Warrior *w[NUMcolors];	// Warriors in the City
	public:
		City( int num )
		{
			Number = num; Strength = 0;
			w[0] = w[1] = NULL;
			Flag = -1; cnt = 0;
		}
		void IncStrength() {
			Strength += 10;
		}
		void ClearLastRecord(){
			w[0] = w[1] = NULL;
		}
		void Test() {
			int wc;	// warrior color
			if( w[0] && !w[1] ) wc = red;
			else if( !w[0] && w[1] ) wc = blue;
			else return;
			Headquarter *h = w[wc]->BringBackStrength( Strength );
			h->ReceiveStrength(Strength);
			printf("%03d:30 %s %s %d ", Clk/60, str_colors[h->GetColor()], str_warriors[w[wc]->GetAttribute()], w[wc]->GetNumber());
			printf("earned %d elements for his headquarter\n", Strength);
			Strength = 0;
		}
		Warrior *CityBattle1( Warrior *survivor );
		void CityBattle2( Warrior *survivor );
		void Explosion();
	friend void ReleaseArrow( City **C ); 
	friend void Marching( Headquarter *Red, Headquarter *Blue, City **C );
	friend void Battle( Headquarter *Red, Headquarter *Blue, City **C );
	friend void ReportWeapon( Headquarter *Red, Headquarter *Blue, City **C );
};

void ReleaseArrow( City **C )
{	//两个相邻的武士可能同时放箭把对方射死。
	for( int i = 0; i < N; i++ )
		for( int j = 0; j < 2; j++ )
		{
			Warrior *w = C[i]->w[j]; if(!w) continue;
			int c = j; Weapon *s = w->GetWeapon(arrow);
			if( s == NULL ) continue;
			else if( s->GetExistence() == false ){
				w->WP[arrow] = NULL;
				continue;
			}
			int l_next = ( j == red ) ? w->GetLocation()+1 : w->GetLocation()-1;
			if( l_next > -1 && l_next < N )
			{
				int cc = (c+1)%2; Warrior *ww = C[l_next]->w[cc];
				if(ww){
					printf("%03d:35 %s %s %d shot", Clk/60, str_colors[c], str_warriors[w->GetAttribute()], w->GetNumber());
					bool alive = w->shotted(ww);	// only clear its strength, do not change the pointer to NULL
					if( alive == false ){
						printf(" and killed %s %s %d", str_colors[cc], str_warriors[ww->GetAttribute()], ww->GetNumber());
					}
					printf("\n");
					s->DecUse(); if( s->GetExistence() == false ) w->WP[arrow] = NULL;
				}
			}
		}
}

void City::Explosion()	//武士不预测对方是否会使用bomb	// 敌人若是ninja就不会反击(或者当作反击不能造成伤害来处理) 
{
	if( !w[red] || !w[blue] ) return;	// there must be two warriors
	if( !w[red]->GetStrength() || !w[blue]->GetStrength() ) return;	// don't set pointer to NULL ( need to judge in Battle)
	int bc;	// bomb color
	bool alive[2];
	memset(alive,true,sizeof(alive));
	for( int i = 0; i < NUMcolors; i++ )
	{
		bc = i;
		if( w[i]->GetWeapon(bomb) == NULL ) bc = -1;
		else if( w[i]->GetWeapon(bomb)->GetExistence() == false ){
			w[i]->ClearWeapon(bomb);
			bc = -1;
		}	// whether the bomb is i
		if( bc == i )
		{ 
			if( Flag == i || Flag == -1 && Number%2 == i )	// i start attack
				alive[i] = w[i]->judge_Back(w[(i+1)%2]);	// whether the other fought back could kill i
			else if( Flag == (i+1)%2 || Flag == -1 && Number%2 == (i+1)%2 )	// the other start attack
				alive[i] = w[i]->judge_Start(w[(i+1)%2]);	// whether the other attack could kill i
		}
	}
	for( int i = 0; i < NUMcolors; i++ )
	{
		if( alive[i] == false ){
			w[i]->ClearStrength(); w[(i+1)%2]->ClearStrength();
			w[i]->SetTag(); w[(i+1)%2]->SetTag();
			printf("%03d:38 %s %s %d used a bomb ", Clk/60, str_colors[i], str_warriors[w[i]->GetAttribute()], w[i]->GetNumber());
			printf("and killed %s %s %d\n", str_colors[(i+1)%2], str_warriors[w[(i+1)%2]->GetAttribute()], w[(i+1)%2]->GetNumber());
		}
	}
}

void Battle( Headquarter *Red, Headquarter *Blue, City **C )
{
	Warrior *survivor[N];
	for( int j = 0; j < N; j++ )
		survivor[j] = C[j]->CityBattle1(NULL);
	for( int i = N-1; i >= 0; i-- )
		if( survivor[i] && survivor[i]->GetColor() == red )
			Red->GiveAward(survivor[i]);
	for( int i = 0; i < N; i++ )
		if( survivor[i] && survivor[i]->GetColor() == blue )
			Blue->GiveAward(survivor[i]);
	for( int j = 0; j < N; j++ )
		C[j]->CityBattle2(survivor[j]);
}
Warrior *City::CityBattle1( Warrior *survivor )
{
	if( !w[0] || !w[1] ) return NULL;
	Warrior *er, *ee;
	if( ( Number%2 == 0 && Flag == -1 ) || Flag == red ){// w[0] - red, w[1] - blue
		er = w[0]; ee = w[1];
	}
	else if( ( Number%2 == 1 && Flag == -1 ) || Flag == blue ){
		er = w[1]; ee = w[0];
	}
	if( w[0]->GetStrength() && w[1]->GetStrength() )
	{
		bool alive = er->StartAttack(ee);
		printf("%03d:40 %s %s %d attacked ", Clk/60, str_colors[er->GetColor()], str_warriors[er->GetAttribute()], er->GetNumber());
		printf("%s %s %d in city %d ", str_colors[ee->GetColor()], str_warriors[ee->GetAttribute()], ee->GetNumber(), Number+1);
		printf("with %d elements and force %d\n", er->GetStrength(), er->GetAttack());
		if( alive == true ){
			alive = ee->FightBack(er);
			if( ee->GetAttribute() != ninja ){
				printf("%03d:40 %s %s %d ", Clk/60, str_colors[ee->GetColor()], str_warriors[ee->GetAttribute()], ee->GetNumber());
				printf("fought back against ");
				printf("%s %s %d in city %d\n", str_colors[er->GetColor()], str_warriors[er->GetAttribute()], er->GetNumber(), Number+1);				
			}
			if( alive == false ){	// er was killed
				printf("%03d:40 %s %s %d ", Clk/60, str_colors[er->GetColor()], str_warriors[er->GetAttribute()], er->GetNumber());
				printf("was killed in city %d\n", Number+1);
			}
		}
		else{	// ee was killed
			printf("%03d:40 %s %s %d ", Clk/60, str_colors[ee->GetColor()], str_warriors[ee->GetAttribute()], ee->GetNumber());
			printf("was killed in city %d\n", Number+1);
		}
	}
	if( er->GetStrength() && !ee->GetStrength() && !ee->GetTag() ) survivor = er;	// shot to death circumstances included
	else if( ee->GetStrength() && !er->GetStrength() && !er->GetTag() ) survivor = ee;
	if( survivor )
	{
		if( survivor == ee ){
			if( er->GetAttribute() == lion )
				ee->ReceiveStrength(er->GetPS());
			if( ee->GetAttribute() == wolf )
				ee->ReceiveWeapon(er);
		}
		else if( survivor == er ){
			if( er->GetAttribute() == wolf ){
//				er->Kill();
				er->ReceiveWeapon(ee);
			}
			if( ee->GetAttribute() == lion )
				er->ReceiveStrength(ee->GetPS());		
		}
		if( survivor->GetAttribute() == dragon )
			survivor->IncMorale();
	}
	else	// !survivor
	{
		switch( er->GetAttribute() ){
			case dragon: er->DecMorale(); break;
			case lion: er->DecLoyalty(); break;
			default: break;
		}
		switch( ee->GetAttribute() ){
			case dragon: ee->DecMorale(); break;
			case lion: ee->DecLoyalty(); break;
			default: break;
		}
	}
	if( er->GetAttribute() == dragon && er->GetStrength() && er->GetMorale() >= 0.8 )
		printf("%03d:40 %s dragon %d yelled in city %d\n", Clk/60, str_colors[er->GetColor()], er->GetNumber(), Number+1);
	if( survivor )
	{	//武士使用bomb和敌人同归于尽的情况下,不算是一场战斗,双方都不能拿走城市的生命元。
		printf("%03d:40 %s %s %d ", Clk/60, str_colors[survivor->GetColor()], str_warriors[survivor->GetAttribute()], survivor->GetNumber());
		printf("earned %d elements for his headquarter\n", Strength);			
	}
	if( !survivor )
	{	//武士使用bomb和敌人同归于尽的情况下,不算是一场战斗,不影响城市的旗帜。//两个相邻的武士可能同时放箭把对方射死。
		if( !ee->GetTag() && !er->GetTag() && ( ee->GetStrength() || er->GetStrength() ) )
			cnt = 0;
	}
	else	// survivor
	{
		int c = survivor->GetColor();
		switch(Flag){
			case -1:
				switch(c){
					case red:
						if( cnt < 0 ) cnt = 1;
						else if( cnt >= 0 && ++cnt == 2 ){
							printf("%03d:40 red flag raised in city %d\n", Clk/60, Number+1);
							Flag = red; cnt = 0;
						}
						break;
					case blue:
						if( cnt > 0 ) cnt = -1;
						else if( cnt <= 0 && --cnt == -2 ){
							printf("%03d:40 blue flag raised in city %d\n", Clk/60, Number+1);
							Flag = blue; cnt = 0;
						}
						break;
					default: break;
				}
				break;
			case red:
				switch(c){
					case red:
						if( cnt < 0 ) cnt++;
						break;
					case blue:
						if( --cnt == -2 ){
							printf("%03d:40 blue flag raised in city %d\n", Clk/60, Number+1);
							Flag = blue; cnt = 0;
						}
						break;
					default: break;
				}
				break;
			case blue:
				switch(c){
					case red:
						if( ++cnt == 2 ){
							printf("%03d:40 red flag raised in city %d\n", Clk/60, Number+1);
							Flag = red; cnt = 0;
						}
						break;
					case blue:
						if( cnt > 0 ) cnt--;
						break;
					default: break;
				}
				break;
			default: break;
		}
	}
	return survivor;
}
void City::CityBattle2( Warrior *survivor )
{
	if( survivor )
	{
		Headquarter *h = survivor->BringBackStrength( Strength );
		h->ReceiveStrength(Strength);
		Strength = 0;
	}
}

void Marching( Headquarter *Red, Headquarter *Blue, City **C )
{
	for( int i = 0; i < N; i++ )
		C[i]->ClearLastRecord();
	for( int i = 0; Red->W[i]; i++ )
	{
		if( Red->W[i]->GetStrength() == 0 )
			continue;
		Red->W[i]->NextStep();
		int l = Red->W[i]->GetLocation();
		if( l < N && l > -1 ){
			if( !C[l]->w[red] ) C[l]->w[red] = Red->W[i];
		}
		else if( l == N ){
			if( !Blue->E[0] ) Blue->E[0] = Red->W[i];
			else if( !Blue->E[1] ) Blue->E[1] = Red->W[i];
		}
	}
	for( int i = 0; Blue->W[i]; i++ )
	{
		if( Blue->W[i]->GetStrength() == 0 )
			continue;
		Blue->W[i]->NextStep();
		int l = Blue->W[i]->GetLocation();
		if( l == -1 ){
			if( !Red->E[0] ) Red->E[0] = Blue->W[i];
			else if( !Red->E[1] ) Red->E[1] = Blue->W[i];
		}
		else if( l < N && l > -1 ){
			if( !C[l]->w[blue] ) C[l]->w[blue] = Blue->W[i];
		}
	}
	int last = -1;
	if( Red->E[1] ) last = 1;
	else if( Red->E[0] ) last = 0;
	if( last >= 0 && Red->E[last]->GetLocation() == -1 ){
		Warrior *w = Red->E[last];
		int a = w->GetAttribute();
		printf("%03d:10 %s %s %d ", Clk/60, str_colors[w->GetColor()], str_warriors[a], w->GetNumber());
		printf("reached red headquarter ");
		if( a == iceman ) w->Proceed();
		printf("with %d elements and force %d\n", w->GetStrength(), w->GetAttack());
		if( last == 1 ){
			printf("%03d:10 red headquarter was taken\n", Clk/60);
			WarEnd = true;
		}
	}
	for( int i = 0; i < N; i++ )
		for( int j = 0; j < 2; j++ )
		{
			Warrior *w = C[i]->w[j]; if(!w) continue;
			int a = w->GetAttribute();
			printf("%03d:10 %s %s %d ", Clk/60, str_colors[j], str_warriors[a], w->GetNumber());
			printf("marched to city %d ", i+1);
			if( a == iceman ) w->Proceed();
			printf("with %d elements and force %d\n", w->GetStrength(), w->GetAttack());
		}
	last = -1;
	if( Blue->E[1] ) last = 1;
	else if( Blue->E[0] ) last = 0;
	if( last >= 0 && Blue->E[last]->GetLocation() == N ){
		Warrior *w = Blue->E[last];
		int a = w->GetAttribute();
		printf("%03d:10 %s %s %d ", Clk/60, str_colors[w->GetColor()], str_warriors[a], w->GetNumber());
		printf("reached blue headquarter ");
		if( a == iceman ) w->Proceed();
		printf("with %d elements and force %d\n", w->GetStrength(), w->GetAttack());
		if( last == 1 ){
			printf("%03d:10 blue headquarter was taken\n", Clk/60);
			WarEnd = true;
		}
	}
}

void Warrior::CheckWeapon()
{	// void ClearWeapon( int i ) { WP[i] = NULL; }
	for( int i = 0; i < NUMweapons; i++ )
		if( WP[i] != NULL && WP[i]->GetExistence() == false )
			WP[i] = NULL;
}
void Warrior::WeaponState()
{
	printf("%03d:55 %s %s %d has ", Clk/60, str_colors[Color], str_warriors[Attribute], Number);	
	CheckWeapon();
	bool armed = false;
	if( WP[arrow] ){
		armed = true;
		printf("arrow(%d)", WP[arrow]->GetUse());
	}
	if( WP[bomb] ){
		if( armed == true ) printf(",");
		else armed = true;
		printf("bomb");
	}
	if( WP[sword] ){
		if( armed == true ) printf(",");
		else armed = true;
		printf("sword(%d)", WP[sword]->GetForce());
	}
	if( armed == false ) printf("no weapon");
	printf("\n");
}
void ReportWeapon( Headquarter *Red, Headquarter *Blue, City **C )
{	//报告时,先按从西向东的顺序所有的红武士报告,然后再从西向东所有的蓝武士报告。
	for( int i = 0; Red->W[i]; i++ )
	{
		Warrior *w = Red->W[i];
		if( w->GetLocation() != -1 || !w->GetStrength() ) continue; 
		w->WeaponState();
	}
	for( int i = 0; i < N; i++ )
		for( int j = 0; j < 2; j++ )
		{
			Warrior *w = C[i]->w[j];
			if( !w || w->GetColor() != red || !w->GetStrength() ) continue;	
			w->WeaponState();
		}
	for( int i = 0; Blue->E[i] && i < 2; i++ )
	{
		Blue->E[i]->WeaponState();
	}
	for( int i = 0; Red->E[i] && i < 2; i++ )
	{
		Red->E[i]->WeaponState();
	}
	for( int i = 0; i < N; i++ )
		for( int j = 0; j < 2; j++ )
		{
			Warrior *w = C[i]->w[j];
			if( !w || w->GetColor() != blue || !w->GetStrength() ) continue;
			w->WeaponState();	
		}
	for( int i = 0; Blue->W[i]; i++ )
	{
		Warrior *w = Blue->W[i];
		if( w->GetLocation() != N || !w->GetStrength() ) continue;
		w->WeaponState();
	}
}

int main()
{
	int ntc; cin >> ntc;	// number of test cases
	for( int tc = 1; tc <= ntc; tc++ )
	{
		int M, T; cin >> M >> N >> R >> K >> T;
		// initial strength of the two headquarters; Number of Cities; Time Limit 
		int sw[NUMwarriors], atk[NUMwarriors];	// strength of warriors; attack of warriors
		for( int i = 0; i < NUMwarriors; i++ )
			cin >> sw[i];
		for( int i = 0; i < NUMwarriors; i++ )
			cin >> atk[i];
		cout << "Case " << tc << ":" << endl;
		WarEnd = false;
		Headquarter Red(M, red, sw, atk), Blue(M, blue, sw, atk);
		City *C[N];
		for( int i = 0; i < N; i++ )
			C[i] = new City(i);
		int res1 = 0, res2 = 0;
		for( Clk = 0; Clk <= T; Clk++ )
		{
			if( WarEnd == true ) break;
			switch(Clk%60)
			{
				case 0:
					if( res1 >= 0 )
						res1 = Red.CreateWarrior(res1);
					if( res2 >= 0 )
						res2 = Blue.CreateWarrior(res2);
					break;
				case 5://在每个小时的第5分,该逃跑的lion就在这一时刻逃跑了。
					Red.RunAway(); Blue.RunAway();
					break;
				case 10:
					Marching(&Red,&Blue,C);
					break;
				case 20:
					for( int i = 0; i < N; i++ )
						C[i]->IncStrength();
					break;
				case 30:
					for( int i = 0; i < N; i++ )
						C[i]->Test();
					break;
				case 35:// 在每个小时的第35分,拥有arrow的武士放箭,对敌人造成伤害。放箭事件应算发生在箭发出的城市。
					ReleaseArrow(C);
					break;
				case 38:// 在每个小时的第38分,拥有bomb的武士评估是否应该使用bomb。如果是,就用bomb和敌人同归于尽。
					for( int i = 0; i < N; i++ )
						C[i]->Explosion();
					break;
				case 40:// 在每个小时的第40分:在有两个武士的城市,会发生战斗。
					Battle(&Red,&Blue,C);
					break;
				case 50:
					Red.Report(); Blue.Report();
					break;
				case 55:// 在每个小时的第55分,每个武士报告其拥有的武器情况
					ReportWeapon(&Red,&Blue,C);
					break;
				default:
					break;
			}
		}
		for( int i = 0; i < N; i++ )
			delete C[i];
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/momo_flamboyant/article/details/79955977