一、题目描述

描述

魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市。

红司令部,City 1,City 2,……,City n,蓝司令部

两军的司令部都会制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值这两种属性。
有的武士可以拥有武器。武器有三种,sword, bomb,和arrow,编号分别为0,1,2。
双方的武士编号都是从1开始计算。红方制造出来的第 n 个武士,编号就是n。同样,蓝方制造出来的第 n 个武士,编号也是n。

不同的武士有不同的特点。
dragon 可以拥有一件武器。编号为n的dragon降生时即获得编号为 n%3 的武器。dragon还有“士气”这个属性,是个浮点数,其值为它降生后其司令部剩余生命元的数量除以造dragon所需的生命元数量。
ninja可以拥有两件武器。编号为n的ninja降生时即获得编号为 n%3 和 (n+1)%3的武器。
iceman有一件武器。编号为n的iceman降生时即获得编号为 n%3 的武器。
lion 有“忠诚度”这个属性,其值等于它降生后其司令部剩余生命元的数目。
wolf没特点。
请注意,在以后的题目里,武士的士气,生命值,忠诚度在其生存期间都可能发生变化,都有作用,武士手中的武器随着使用攻击力也会发生变化。

武士在刚降生的时候有一个生命值。

在每个整点,双方的司令部中各有一个武士降生。

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

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

制造武士需要生命元。

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

如果司令部中的生命元不足以制造某个按顺序应该制造的武士,那么司令部就试图制造下一个。如果所有武士都不能制造了,则司令部停止制造武士。
给定一个时间,和双方司令部的初始生命元数目,要求你将从0点0分开始到双方司令部停止制造武士为止的所有事件按顺序输出。
一共有两种事件,其对应的输出样例如下:

  1. 武士降生
    输出样例: 004 blue lion 5 born with strength 5,2 lion in red headquarter
    表示在 4点整,编号为5的蓝魔lion武士降生,它降生时生命值为5,降生后蓝魔司令部里共有2个lion武士。(为简单起见,不考虑单词的复数形式)注意,每制造出一个新的武士,都要输出此时司令部里共有多少个该种武士。
    如果造出的是dragon,那么还要输出一行,例:
    It has a arrow,and it’s morale is 23.34
    表示该dragon降生时得到了arrow,其士气是23.34(为简单起见,本题中arrow前面的冠词用a,不用an,士气精确到小数点后面2位,四舍五入)
    如果造出的是ninja,那么还要输出一行,例:
    It has a bomb and a arrow
    表示该ninja降生时得到了bomb和arrow。
    如果造出的是iceman,那么还要输出一行,例:
    It has a sword
    表示该iceman降生时得到了sword。
    如果造出的是lion,那么还要输出一行,例:
    It’s loyalty is 24
    表示该lion降生时的忠诚度是24。
  2. 司令部停止制造武士
    输出样例: 010 red headquarter stops making warriors
    表示在 10点整,红方司令部停止制造武士

输出事件时:

首先按时间顺序输出;

同一时间发生的事件,先输出红司令部的,再输出蓝司令部的。

输入

第一行是一个整数,代表测试数据组数。

每组测试数据共两行。

第一行,一个整数M。其含义为: 每个司令部一开始都有M个生命元( 1 <= M <= 10000)

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

样例:

1
2
3
1
20
3 4 5 6 7

输出

对每组测试数据,要求输出从0时0分开始,到双方司令部都停止制造武士为止的所有事件。
对每组测试数据,首先输出“Case:n" n是测试数据的编号,从1开始
接下来按恰当的顺序和格式输出所有事件。每个事件都以事件发生的时间开头,时间以小时为单位,有三位。
样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Case:1
000 red iceman 1 born with strength 5,1 iceman in red headquarter
It has a bomb
000 blue lion 1 born with strength 6,1 lion in blue headquarter
It's loyalty is 14
001 red lion 2 born with strength 6,1 lion in red headquarter
It's loyalty is 9
001 blue dragon 2 born with strength 3,1 dragon in blue headquarter
It has a arrow,and it's morale is 3.67
002 red wolf 3 born with strength 7,1 wolf in red headquarter
002 blue ninja 3 born with strength 4,1 ninja in blue headquarter
It has a sword and a bomb
003 red headquarter stops making warriors
003 blue iceman 4 born with strength 5,1 iceman in blue headquarter
It has a bomb
004 blue headquarter stops making warriors

二、简要思路

在写这个程序之前,我把先前的代码重新改造了一下(请看上一篇本人的博文)。在先前的代码中,我在主函数定义了一个基类指针数组,并以此在之后制造武士的过程中运用多态,通过记录武士出场顺序的数组作为下标来访问该指针数组,这样就不用专门写一个switch分支语句来判断输出的是什么武士。这样做的好处是可以简化代码。

但是在这个程序中,我打算在Command类里用一个myWarrior的基类指针数组来存储每一个成功生成的武士,因此主函数的基类指针数组其实是多此一举的,我定义了一个p数组,这个数组按照武士默认顺序记录了每种武士的生命值,这样,我通过记录武士出场顺序的数组作为下标来访问该数组,这样做显然比先前的效率更高,也更符合逻辑。

好,我们来理一理思路,我们以红司令部作为例子,其实是这个样子的:

上面的图片展示了默认顺序、记录每种武士的生命值的数组p以及记录红司令部武士们的生成顺序的数组Order。我们用OrderCount来作为循环变量,比如当OrderCount=1时,那么就可以访问redOrder[OrderCount],即redOrder[1]=3,这个3告诉我们第一个生成的应该是iceman,好,我们再去访问iceman对应的生命值,为5,这样就能进行后续比较、生成操作了。对,就是下面这个过程:

在Warrior基类派生出五种武士类,它们的构造函数将直接输出生成信息,以及武器信息、士气信息和忠诚度信息,这也意味着我要写五遍这样类似的代码,而且需要将司令部的各种信息作为这些构造函数的形参,例如:

1
2
3
Dragon(int _No, const int _HP, string belong, const double CommandHP, int WarriorKindNumber);
//这些参数从左到右依次是:武士编号,武士生命值,武士所属司令部(字符串),
//武士所属司令部剩余生命元 ,武士所属司令部中同种类武士数量

虽然有点麻烦,但是这样写显然是更符合逻辑的。写完这个程序之后我专门到网上查找了其他人的代码,发现基本都是写在了司令部类的成员函数里,这显然不符合逻辑。我写这个题目其实不是为了拿个通过码,可能他们只是想快点AC吧。

我这样写又有一个好处:代码的逻辑性增强了,而且司令部的制造武士函数也不用那么复杂了,直接调用一个构造函数就搞定了结果的输出。

三、初步代码

温馨提示:本代码不能作为答案直接贴在评测系统上,因为输出结果跟题目要求是不一样的!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#include <iostream>
#include <string>
#include <iomanip>
#include <ctime>
using namespace std;
const int WARRIOR_NUM = 5;
const int WEAPON_NUM = 2;
enum warrior{total=0, dragon, ninja, iceman, lion, wolf};
//1dragon 2ninja 3iceman 4lion 5wolf
//0sword 1bomb 2arrow

//No.0
class Warrior{
protected:
int No;
int HP;
short WeaponHP[WEAPON_NUM+1];
string Name;
public:
friend class Command;
virtual string CreateWeapon(int No);
};

string Warrior::CreateWeapon(int _No)
{
_No = _No % 3;
switch(_No)
{
case 0: WeaponHP[0]=1; return "sword"; break;
case 1: WeaponHP[1]=1; return "bomb"; break;
case 2: WeaponHP[2]=1; return "arrow"; break;
default: break;
}
}

//No.1
class Dragon:public Warrior{
private:
double Morale;
public:
Dragon(int _No, const int _HP, string belong, const double CommandHP, int WarriorKindNumber);
//这些参数从左到右依次是:武士编号,武士生命值,武士所属司令部(字符串),
//武士所属司令部剩余生命元 ,武士所属司令部中同种类武士数量 ,下同
};

Dragon::Dragon(int _No, const int _HP, string belong, const double CommandHP, int WarriorKindNumber)
{
No=_No; HP=_HP; Name="dragon";
Morale = CommandHP/HP;
cout<<belong<<" "<<this->Name<<" "<<this->No<<" born with strength "<<this->HP<<", ";
cout<<WarriorKindNumber<<" "<<this->Name<<" in "<<belong<<" headquarter, ";
cout<<"rest HP = "<<(int)CommandHP<<endl;
cout<<"It has a "<<this->CreateWeapon(No)<<", and it's morale is "<<setiosflags(ios::fixed)<<setprecision(2)<<Morale<<endl;
}

//No.2
class Ninja:public Warrior{
public:
Ninja(int _No, const int _HP, string belong, const int CommandHP, int WarriorKindNumber);
};

Ninja::Ninja(int _No, const int _HP, string belong, const int CommandHP, int WarriorKindNumber)
{
No=_No; HP=_HP; Name="ninja";
cout<<belong<<" "<<this->Name<<" "<<this->No<<" born with strength "<<this->HP<<", ";
cout<<WarriorKindNumber<<" "<<this->Name<<" in "<<belong<<" headquarter, ";
cout<<"rest HP = "<<CommandHP<<endl;
cout<<"It has a "<<this->CreateWeapon(No)<<" and a "<<this->CreateWeapon(No+1)<<endl;
}

//No.3
class Iceman:public Warrior{
public:
Iceman(int _No, const int _HP, string belong, const int CommandHP, int WarriorKindNumber);
};

Iceman::Iceman(int _No, const int _HP, string belong, const int CommandHP, int WarriorKindNumber)
{
No=_No; HP=_HP; Name="iceman";
cout<<belong<<" "<<this->Name<<" "<<this->No<<" born with strength "<<this->HP<<", ";
cout<<WarriorKindNumber<<" "<<this->Name<<" in "<<belong<<" headquarter, ";
cout<<"rest HP = "<<CommandHP<<endl;
cout<<"It has a "<<this->CreateWeapon(No)<<endl;
}

//No.4
class Lion:public Warrior{
private:
int Loyalty;
public:
Lion(int _No, const int _HP, string belong, const int CommandHP, int WarriorKindNumber);
};

Lion::Lion(int _No, const int _HP, string belong, const int CommandHP, int WarriorKindNumber)
{
No=_No; HP=_HP; Name="lion"; Loyalty=CommandHP;
cout<<belong<<" "<<this->Name<<" "<<this->No<<" born with strength "<<this->HP<<", ";
cout<<WarriorKindNumber<<" "<<this->Name<<" in "<<belong<<" headquarter, ";
cout<<"rest HP = "<<CommandHP<<endl;
cout<<"It's loyalty is "<<Loyalty<<endl;
}

//No.5
class Wolf:public Warrior{
public:
Wolf(int _No, const int _HP, string belong, const int CommandHP, int WarriorKindNumber);
};

Wolf::Wolf(int _No, const int _HP, string belong, const int CommandHP, int WarriorKindNumber)
{
No=_No; HP=_HP; Name="wolf";
cout<<belong<<" "<<this->Name<<" "<<this->No<<" born with strength "<<this->HP<<", ";
cout<<WarriorKindNumber<<" "<<this->Name<<" in "<<belong<<" headquarter, ";
cout<<"rest HP = "<<CommandHP<<endl;
}

//====================================================
class Command{
private:
string Name;
short OrderCount;//循环遍历武士顺序数组
int HP;
int WarriorNumber[WARRIOR_NUM+1];//记录总数以及每个武士的数量 ,下标为0的元素存储总数
Warrior *myWarrior[200]; //指向每一个成功生成的武士
public:
static int time;//游戏系统时间
short Order[WARRIOR_NUM+1];//制造武士的顺序记录,即武士顺序数组
Command(string _Name, const short _Order[], const int _HP);
~Command();
bool CreateWarrior(short p[]);
void StopCreateWarrior();
};
int Command::time = -1;//静态成员变量必须进行初始化

Command::Command(string _Name, const short _Order[], const int _HP):Name(_Name), HP(_HP)
{
OrderCount = 1;
for(int i=0; i<=WARRIOR_NUM; i++) //这里做的工作是复制+初始化
{
Order[i] = _Order[i];
WarriorNumber[i] = 0;
}
}

Command::~Command()
{
while(WarriorNumber[total]) //内存释放很重要,别忘了
{
delete myWarrior[WarriorNumber[total]];
WarriorNumber[total]--;
}
}

bool Command::CreateWarrior(short p[])
{
if( HP<p[1] && HP<p[2] && HP<p[3] && HP<p[4] && HP<p[5] ) return 0;
while(HP < p[Order[OrderCount]])
{
OrderCount++;
if(OrderCount==WARRIOR_NUM+1) OrderCount=1;
}
short ord = Order[OrderCount];
WarriorNumber[total]++;
WarriorNumber[ord]++;
HP -= p[ord];
short No = WarriorNumber[total];
cout<<setw(3)<<setfill('0')<<time<<" ";
switch(ord)
{
case 1: myWarrior[No]=new Dragon(No, p[1], Name, (double)HP, WarriorNumber[ord]); break;
case 2: myWarrior[No]=new Ninja(No, p[2], Name, HP, WarriorNumber[ord]); break;
case 3: myWarrior[No]=new Iceman(No, p[3], Name, HP, WarriorNumber[ord]); break;
case 4: myWarrior[No]=new Lion(No, p[4], Name, HP, WarriorNumber[ord]); break;
case 5: myWarrior[No]=new Wolf(No, p[5], Name, HP, WarriorNumber[ord]); break;
default: break;
}
OrderCount++;
if(OrderCount == WARRIOR_NUM+1) OrderCount=1;
return 1;
}

void Command::StopCreateWarrior()
{
cout<<setw(3)<<setfill('0')<<time<<" "<<this->Name<<" headquarter stops making warriors"<<endl;
}

int main()
{
int n=1;
short redOrder[WARRIOR_NUM+1]={0, iceman, lion, wolf, ninja, dragon};
short blueOrder[WARRIOR_NUM+1]={0, lion, dragon, ninja, iceman, wolf};
short M, dm, nm, im, lm, wm;
clock_t startTime, endTime;
//cin>>n;
while(n--)
{
cin>>M;//输入司令部生命元
cin>>dm>>nm>>im>>lm>>wm;//输入每种武士的生命值
startTime = clock();
Command red("red", redOrder, M), blue("blue", blueOrder, M);
short p[WARRIOR_NUM+1] = {0, dm, nm, im, lm, wm}; //用数组存储每种武士的生命值
bool redCreate = 1, blueCreate = 1;//记录司令部是否能进行制造武士,1表示可以,0则相反
Command::time = -1;
while(redCreate || blueCreate)//开始制造武士
{
Command::time ++;//系统时间加1
//制造武士的函数既可以完成制造任务,又可以返回制造情况:返回1表示制造成功,
//而返回0则说明一个都制造不了, 同时还要使布尔变量red(blue)Create变成0
if(redCreate == 1 && red.CreateWarrior(p) == 0){redCreate = 0; red.StopCreateWarrior();}
if(blueCreate == 1 && blue.CreateWarrior(p) == 0){blueCreate = 0; blue.StopCreateWarrior();}
cout<<endl;
}
}
endTime = clock();
cout<<"time:"<<(double)(endTime - startTime) <<"ms"<<endl;
return 0;
}

输入:

1
2
60
3 4 5 6 7

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
000 red iceman 1 born with strength 5, 1 iceman in red headquarter, rest HP = 55
It has a bomb
000 blue lion 1 born with strength 6, 1 lion in blue headquarter, rest HP = 54
It's loyalty is 54

001 red lion 2 born with strength 6, 1 lion in red headquarter, rest HP = 49
It's loyalty is 49
001 blue dragon 2 born with strength 3, 1 dragon in blue headquarter, rest HP = 51
It has a arrow, and it's morale is 17

002 red wolf 3 born with strength 7, 1 wolf in red headquarter, rest HP = 42
002 blue ninja 3 born with strength 4, 1 ninja in blue headquarter, rest HP = 47
It has a sword and a bomb

003 red ninja 4 born with strength 4, 1 ninja in red headquarter, rest HP = 38
It has a bomb and a arrow
003 blue iceman 4 born with strength 5, 1 iceman in blue headquarter, rest HP = 42
It has a bomb

004 red dragon 5 born with strength 3, 1 dragon in red headquarter, rest HP = 35
It has a arrow, and it's morale is 11.67
004 blue wolf 5 born with strength 7, 1 wolf in blue headquarter, rest HP = 35

005 red iceman 6 born with strength 5, 2 iceman in red headquarter, rest HP = 30
It has a sword
005 blue lion 6 born with strength 6, 2 lion in blue headquarter, rest HP = 29
It's loyalty is 29

006 red lion 7 born with strength 6, 2 lion in red headquarter, rest HP = 24
It's loyalty is 24
006 blue dragon 7 born with strength 3, 2 dragon in blue headquarter, rest HP = 26
It has a bomb, and it's morale is 8.67

007 red wolf 8 born with strength 7, 2 wolf in red headquarter, rest HP = 17
007 blue ninja 8 born with strength 4, 2 ninja in blue headquarter, rest HP = 22
It has a arrow and a sword

008 red ninja 9 born with strength 4, 2 ninja in red headquarter, rest HP = 13
It has a sword and a bomb
008 blue iceman 9 born with strength 5, 2 iceman in blue headquarter, rest HP = 17
It has a sword

009 red dragon 10 born with strength 3, 2 dragon in red headquarter, rest HP = 10
It has a bomb, and it's morale is 3.33
009 blue wolf 10 born with strength 7, 2 wolf in blue headquarter, rest HP = 10

010 red iceman 11 born with strength 5, 3 iceman in red headquarter, rest HP = 5
It has a arrow
010 blue lion 11 born with strength 6, 3 lion in blue headquarter, rest HP = 4
It's loyalty is 4

011 red ninja 12 born with strength 4, 3 ninja in red headquarter, rest HP = 1
It has a sword and a bomb
011 blue dragon 12 born with strength 3, 3 dragon in blue headquarter, rest HP = 1
It has a sword, and it's morale is 0.33

012 red headquarter stops making warriors
012 blue headquarter stops making warriors

time:724.00ms

运行时间比较长,其实是cout造成的。