描述

魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为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。

sword的攻击力是使用者当前攻击力的20%(去尾取整)。

bomb的攻击力是使用者当前攻击力的40%(去尾取整),但是也会导致使用者受到攻击,对使用者的攻击力是对敌人取整后的攻击力的1/2(去尾取整)。Bomb一旦使用就没了。

arrow的攻击力是使用者当前攻击力的30%(去尾取整)。一个arrow用两次就没了。

武士降生后就朝对方司令部走,在经过的城市如果遇到敌人(同一时刻每个城市最多只可能有1个蓝武士和一个红武士),就会发生战斗。战斗的规则是:

  1. 在奇数编号城市,红武士先发起攻击
  2. 在偶数编号城市,蓝武士先发起攻击
  3. 战斗开始前,双方先对自己的武器排好使用顺序,然后再一件一件地按顺序使用。编号小的武器,排在前面。若有多支arrow,用过的排在前面。排好序后,攻击者按此排序依次对敌人一件一件地使用武器。如果一种武器有多件,那就都要用上。每使用一件武器,被攻击者生命值要减去武器攻击力。如果任何一方生命值减为0或小于0即为死去。有一方死去,则战斗结束。
  4. 双方轮流使用武器,甲用过一件,就轮到乙用。某一方把自己所有的武器都用过一轮后,就从头开始再用一轮。如果某一方没有武器了,那就挨打直到死去或敌人武器用完。武器排序只在战斗前进行,战斗中不会重新排序
  5. 如果双方武器都用完且都还活着,则战斗以平局结束。如果双方都死了,也算平局。
  6. 有可能由于武士自身攻击力太低,而导致武器攻击力为0。攻击力为0的武器也要使用。如果战斗中双方的生命值和武器的状态都不再发生变化,则战斗结束,算平局。
  7. 战斗的胜方获得对方手里的武器。武士手里武器总数不超过10件。缴获武器时,按照武器种类编号从小到大缴获。如果有多件arrow,优先缴获没用过的。
  8. 如果战斗开始前双方都没有武器,则战斗视为平局。如果先攻击方没有武器,则由后攻击方攻击。

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

0

编号为n的dragon降生时即获得编号为n%3 的武器。dragon在战斗结束后,如果还没有战死,就会欢呼。

1

编号为n的ninjia降生时即获得编号为n%3 和(n+1)%3的武器。ninja 使用bomb不会让自己受伤。

2

编号为n的iceman降生时即获得编号为n%3 的武器。iceman每前进一步,生命值减少10%(减少的量要去尾取整)。

3

编号为n的lion降生时即获得编号为n%3 的武器。lion 有“忠诚度”这个属性,其初始值等于它降生之后其司令部剩余生命元的数目。每前进一步忠诚度就降低K。忠诚度降至0或0以下,则该lion逃离战场,永远消失。但是已经到达敌人司令部的lion不会逃跑。lion在己方司令部可能逃跑。

4

wolf降生时没有武器,但是在战斗开始前会抢到敌人编号最小的那种武器。如果敌人有多件这样的武器,则全部抢来。Wolf手里武器也不能超过10件。如果敌人arrow太多没法都抢来,那就先抢没用过的。如果敌人也是wolf,则不抢武器。

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

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

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

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

制造武士需要生命元。

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

如果司令部中的生命元不足以制造某本该造的武士,那就从此停止制造武士。

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

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

在每个小时的第35分:在有wolf及其敌人的城市,wolf要抢夺对方的武器。

在每个小时的第40分:在有两个武士的城市,会发生战斗。

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

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

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

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

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

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

  1. 武士降生

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

表示在0点0分,编号为1的蓝魔dragon武士降生

如果造出的是lion,那么还要多输出一行,例:

000:00 blue lion 1 born

Its loyalty is 24

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

  1. lion逃跑

输出样例:000:05 blue lion 1 ran away

表示在0点5分,编号为1的蓝魔lion武士逃走

  1. 武士前进到某一城市

输出样例:

000:10 red iceman 1 marched to city 1 with 20 elements and force 30

表示在0点10分,红魔1号武士iceman前进到1号城市,此时他生命值为20,攻击力为30

对于iceman,输出的生命值应该是变化后的数值

  1. wolf抢敌人的武器

000:35 blue wolf 2 took 3 bomb from red dragon 2 in city 4

表示在0点35分,4号城市中,红魔1号武士wolf 抢走蓝魔2号武士dragon 3个bomb。为简单起见,武器不写复数形式

  1. 报告战斗情况

战斗只有3种可能的输出结果:

000:40 red iceman 1 killed blue lion 12 in city 2 remaining 20 elements

表示在0点40分,1号城市中,红魔1号武士iceman 杀死蓝魔12号武士lion后,剩下生命值20

000:40 both red iceman 1 and blue lion 12 died in city 2

注意,把红武士写前面

000:40 both red iceman 1 and blue lion 12 were alive in city 2

注意,把红武士写前面

  1. 武士欢呼

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

  1. 武士抵达敌军司令部

输出样例:001:10 red iceman 1 reached blue headquarter with 20 elements and force 30

(此时他生命值为20,攻击力为30)对于iceman,输出的生命值和攻击力应该是变化后的数值

  1. 司令部被占领

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

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

000:50 100 elements in red headquarter

000:50 120 elements in blue headquarter

表示在0点50分,红方司令部有100个生命元,蓝方有120个

10)武士报告情况

000:55 blue wolf 2 has 2 sword 3 bomb 0 arrow and 7 elements

为简单起见,武器都不写复数形式。elements一律写复数,哪怕只有1个

交代武器情况时,次序依次是:sword,bomb, arrow。

输出事件时:

首先按时间顺序输出;

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

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

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

对于同一城市,同一时间发生的事情,先输出红方的,后输出蓝方的。

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

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

输入

第一行是t,代表测试数据组数

每组样例共三行。

第一行,4个整数 M,N,K, T。其含义为:
每个司令部一开始都有M个生命元( 1 <= M <= 100000)
两个司令部之间一共有N个城市( 1 <= N <= 20 )
lion每前进一步,忠诚度就降低K。(0<=K<=100)
要求输出从0时0分开始,到时间T为止(包括T) 的所有事件。T以分钟为单位,0 <= T <= 6000

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

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

输出

对每组数据,先输出一行:

Case n:

如对第一组数据就输出 Case 1:

然后按恰当的顺序和格式输出到时间T为止发生的所有事件。每个事件都以事件发生的时间开头,时间格式是“时: 分”,“时”有三位,“分”有两位。

样例输入

1
20 1 10 400
20 20 30 10 20
5 5 5 5 5

样例输出

Case 1:
000:00 blue lion 1 born
Its loyalty is 10
000:10 blue lion 1 marched to city 1 with 10 elements and force 5
000:50 20 elements in red headquarter
000:50 10 elements in blue headquarter
000:55 blue lion 1 has 0 sword 1 bomb 0 arrow and 10 elements
001:05 blue lion 1 ran away
001:50 20 elements in red headquarter
001:50 10 elements in blue headquarter
002:50 20 elements in red headquarter
002:50 10 elements in blue headquarter
003:50 20 elements in red headquarter
003:50 10 elements in blue headquarter
004:50 20 elements in red headquarter
004:50 10 elements in blue headquarter
005:50 20 elements in red headquarter
005:50 10 elements in blue headquarter

提示

请注意浮点数精度误差问题。OJ上的编译器编译出来的可执行程序,在这方面和你电脑上执行的程序很可能会不一致。5 * 0.3 的结果,有的机器上可能是 15.00000001,去尾取整得到15,有的机器上可能是14.9999999,去尾取整后就变成14。因此,本题不要写 5 * 0.3,要写 5 * 3 / 10。

来源

Guo Wei

我的代码

分析和收获什么的……等有时间再写吧……

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
using namespace std;
/*需要完成的功能:
* 城市编号、武器攻击力、战斗开始前给武器排序
* 如果司令部生命元不足以制造就停止制造
* 战斗规则
* 不同类武士的不同特点:欢呼、逃跑、抢夺武器等
* 时间:精确到分
* 事件:逃跑、前进、抢夺、战斗、生命元数量和武器情况报告、占领司令部战争结束
*/
/*计划
* weapon类:指向主人的指针、刷新攻击力函数、耐久度
* warrior类:武器向量(指向武器的指针)、武器排序(已有武器排序、抢夺武器排序)、location
* 武士移动:soldierPool
* 战斗:从西到东输出,战斗后胜方缴获对方武器
* 时间线:born lionescape march wolfTakeWeapon battle reportPower reportStatus
* 武器:使用前的排序、抢夺前排序,注意wolf的抢夺和战胜后抢夺的规则不同
*/
int makingSeq[2][5] = { {2,3,4,1,0},{3,0,1,2,4} };     // {redSeq,blueSeq}
int lifeAll, cityNum, loyaltyCost, stopTime, warrLife[5], minLife, warrATK[5];      //lifeD, lifeN, lifeI, lifeL, lifeW;
int curr_hour = 0;
int curr_minute = 0;
void printTime() {cout << setw(3) << setfill('0') << curr_hour;cout << ":" << setw(2) << setfill('0') << curr_minute;
}
class Headquarter;
class Warrior;
class Dragon;
class Ninja;
class Iceman;
class Lion;
class Wolf;
class CWeapon;
class CSword;
class CBomb;
class CArrow;
class BattleFront;class CWeapon {protected:int type;// 0 sword 1 bomb 2 arrowint ATK;//攻击力int durability;//Warrior* currOwner;//当前主人
public:void setATK(int ownerATK) {switch (type) {case 0:ATK = ownerATK * 2 / 10; break;case 1:ATK = ownerATK * 4 / 10; break;case 2:ATK = ownerATK * 3 / 10; break;default:cout << "set ATK error!" << endl; break;}}CWeapon(int type = 0, int ownerATK = 0, int dur = 0) :type(type), durability(dur) {setATK(ownerATK);}virtual ~CWeapon() {};    string getWeaponName() {switch (type) {case 0:return "sword";case 1:return "bomb";case 2:return "arrow";default:return "error!!!";}}friend int compareWeaponUse(const void* p1, const void* p2);friend int compareWeaponTake(const void* wpn1, const void* wpn2);friend class Warrior;friend class Wolf;
};class CSword :public CWeapon {public:CSword(int ownerATK = 0) :CWeapon(0, ownerATK, -1) {}~CSword() {};
};
class CBomb :public CWeapon {public:CBomb(int ownerATK = 0) :CWeapon(1, ownerATK, 1) {}~CBomb() {};
};
class CArrow :public CWeapon {public:CArrow(int ownerATK = 0) :CWeapon(2, ownerATK, 2) {}//耐久度=2~CArrow() {};
};int compareWeaponUse(const void* p1, const void* p2) {//如果写成成员函数,就会多一个this参数CWeapon* wpn1 = (CWeapon*)p1;CWeapon* wpn2 = (CWeapon*)p2;if (wpn1->type != wpn2->type)return wpn1->type < wpn2->type;if (wpn1->type == 2)return wpn1->durability < wpn2->durability; // 使用时,弓箭耐久度高的排后面//compare函数需要满足严格弱序//运行到此处说明两种武器同样是sword或同样是bomb,或者是自己与自己相比:应当返回falsereturn false;
}int compareWeaponTake(const void* p1, const void* p2) {CWeapon* wpn1 = (CWeapon*)p1;CWeapon* wpn2 = (CWeapon*)p2;if (wpn1->type != wpn2->type)return wpn1->type < wpn2->type;if (wpn1->type == 2)return wpn1->durability > wpn2->durability; // 抢夺时,弓箭耐久度高的排后面return false;
}class Headquarter {private:int lifeSource = 0;        // 司令部剩余生命元int side;    // 0 red, 1 bluestring sideName;bool isStopped = false;        // 是否停止制造int currWarrior = 0;      //当前武士类别,从0开始int numTotal = 0;      //武士总编号,初始为1
public:friend class Warrior;friend class Dragon;friend class Lion;Headquarter(int i) :side(i) { if (side)sideName = "blue"; else sideName = "red"; };     // constructor~Headquarter() {};void reset() {lifeSource = lifeAll;isStopped = false;     //是否停止制造currWarrior = 0;       //当前武士类别,从0开始numTotal = 0;      //武士总编号,初始为1}void makeWarrior();void reportLifeSource() {printTime();cout << " " << lifeSource << " elements in " << sideName << " headquarter" << endl;}
};
Headquarter redHQ(0), blueHQ(1);class Warrior {protected:int armNum; //武器数量vector<CWeapon*> arms;int armSeq = 0;int armCount[3] = {};//0-sword 1-bomb 2-arrowint warriorNum; //武士编号int warriorType = 0; //武士类别,从0开始int side; // 0-red 1-blue string sideName;string warriorName = "\0";int life;bool _isDead = false;int location;int ATK;Headquarter* currHQ;
public:friend class Headquarter;friend class BattleFront;friend class Wolf;friend int compareWarrior(const void* p1, const void* p2);Warrior(int armNum = 0, int num = 0, int side = 0, int life = 1, int atk = 0, Headquarter* currhq = NULL) :armNum(armNum), warriorNum(num), side(side), life(life),ATK(atk), currHQ(currhq) {for (int i = 0; i < armNum; ++i) {int j = (warriorNum + i) % 3;armCount[j]++;switch (j) {case 0:arms.push_back(new CSword(ATK)); break;case 1:arms.push_back(new CBomb(ATK)); break;case 2:arms.push_back(new CArrow(ATK)); break;}}if (side)sideName = "blue";else sideName = "red";if (side)location = cityNum + 1;else location = 0;}virtual void warriorBorn() {printTime();cout << " " << sideName << " " << warriorName << " " << currHQ->numTotal << " born" << endl;}void Die() { _isDead = true; }bool isDead() {if (life <= 0)this->Die();return _isDead;}void removeWastedArms() {if (arms.empty())return;for (auto iter = arms.begin(); iter != arms.end(); ++iter) {//需要考虑到相邻两个武器耐久都为0的情况while ((*iter)->durability == 0) {armCount[(*iter)->type]--;//先减少数量,再eraseiter = arms.erase(iter);if (iter == arms.end())break;}if (iter == arms.end())break;}}void refreshArmsUse() {armSeq = 0;this->removeWastedArms();if (!arms.empty()) {//qsort(arms[0], arms.size(), sizeof(CWeapon*), &compareWeaponUse);sort(arms.begin(), arms.end(), compareWeaponUse);}}void refreshArmsTake() {this->removeWastedArms();if (!arms.empty()) {//qsort(arms[0], arms.size(), sizeof(CWeapon*), &compareWeaponTake);sort(arms.begin(), arms.end(), compareWeaponTake);}}CWeapon* getWeapon() {if (armSeq >= arms.size())armSeq = 0;        return arms[armSeq++];}void fight(Warrior* wrr) {this->removeWastedArms();if (this->arms.empty())return;CWeapon* currWpn = getWeapon();wrr->life -= currWpn->ATK;//cout << this->sideName << " " << this->warriorName << " " << this->warriorNum << " attack " <<//    wrr->sideName << " " << wrr->warriorName << " " << wrr->warriorNum << " using " <<// currWpn->getWeaponName() << " force " << currWpn->ATK << endl;if (currWpn->type == 1 && this->warriorType != 1)this->life -= int(currWpn->ATK / 2);if (currWpn->type != 0)currWpn->durability--;this->removeWastedArms();wrr->removeWastedArms();this->isDead(); wrr->isDead();};void takeArms(Warrior* wrr) {if (wrr->arms.empty())return;wrr->refreshArmsTake();for (auto iter = wrr->arms.begin(); iter != wrr->arms.end(); ++iter) {if (this->arms.size() >= 10)break;this->arms.push_back(*iter);this->armCount[(*iter)->type]++;this->arms.back()->setATK(this->ATK);}wrr->arms.clear();}bool isHarmless() {//如果武士所有的武器都用完,或是剩余武器攻击力全为0,则为harmlessif (arms.empty())return true;//所有武器都用完了if (armCount[1] != 0 || armCount[2] != 0)return false;//有炸弹或箭矢,可以使用for (auto iter = arms.begin(); iter != arms.end(); ++iter) {if ((*iter)->type == 0 && (*iter)->ATK != 0)return false;//存在有攻击力不为0的sword,可以使用}return true;//没有可造成伤害的武器了}
};class Dragon :public Warrior {public:Dragon(int num, int side, int life, int atk, Headquarter* currhq) :Warrior(1, num, side, life, atk, currhq) {warriorName = "dragon";warriorType = 0;}~Dragon() {};
};
class Ninja :public Warrior {public:Ninja(int num, int side, int life,int atk, Headquarter* currhq) : Warrior(2, num, side, life, atk, currhq) {warriorName = "ninja";warriorType = 1;}~Ninja() {};
};
class Iceman :public Warrior {public:Iceman(int num, int side, int life,int atk, Headquarter* currhq) :Warrior(1, num, side, life,atk, currhq) {warriorName = "iceman";warriorType = 2;}~Iceman() {};
};
class Lion :public Warrior {private:int loyalty;
public:Lion(int num, int side, int life,int atk, Headquarter* currhq) :Warrior(1, num, side, life,atk, currhq) {warriorName = "lion";loyalty = currHQ->lifeSource;warriorType = 3;}~Lion() {};void warriorBorn() {Warrior::warriorBorn();cout << "Its loyalty is " << loyalty << endl;}friend class BattleFront;
};
class Wolf : public Warrior {public:Wolf(int num, int side, int life,int atk, Headquarter* currhq) :Warrior(0, num, side, life,atk, currhq) {warriorName = "wolf";warriorType = 4;}~Wolf() {};void takeArm_Wolf(Warrior* wrr) {if (wrr->arms.empty())return;wrr->refreshArmsTake();//不用for循环,因为erase后相当于++iter,然后会和for里的++iter搞混;或者删除for里的++iter//for (auto iter = wrr->arms.begin(); iter < wrr->arms.end(); ++iter) {//   if (this->arms.size() >= 10)break;// this->arms.push_back(*iter);//   this->arms.back()->setATK(this->ATK);//    this->armCount[(*iter)->type]++;//  wrr->armCount[(*iter)->type]--;// takeCount++;//    takeWeaponName = (*iter)->getWeaponName();//    int originalType = (*iter)->type;// iter = wrr->arms.erase(iter);// if (iter == wrr->arms.end())break;//   if ((*iter)->type != originalType)break;//}auto iter = wrr->arms.begin();int takeWeaponType = (*iter)->type;int takeCount = 0;string takeWeaponName;while ((*iter)->type == takeWeaponType && this->arms.size() <= 10) {takeWeaponName = (*iter)->getWeaponName();this->arms.push_back(*iter);this->arms.back()->setATK(this->ATK);this->armCount[(*iter)->type]++;wrr->armCount[(*iter)->type]--;takeCount++;iter = wrr->arms.erase(iter);if (iter == wrr->arms.end())break;}if (takeCount != 0) {printTime();cout << " " << this->sideName << " wolf " << this->warriorNum << " took " << takeCount << " " << takeWeaponName <<" from " << wrr->sideName << " " << wrr->warriorName << " " << wrr->warriorNum << " in city " << this->location << endl;}}
};
int compareWarrior(const void* p1, const void* p2) {//注意 sort中使用的compare函数需要满足严格弱序条件Warrior* wrr1 = (Warrior*)p1;Warrior* wrr2 = (Warrior*)p2;if (wrr1->location != wrr2->location)return wrr1->location < wrr2->location;//location相同,一红一蓝return wrr1->side < wrr2->side; //0-red first
}
class BattleFront {private:vector<Warrior*>warriorLine; //兵线,储存所有武士,以从西到东排序,同一城市的红蓝武士,红方在西边
public:BattleFront() {};~BattleFront() {int len = (int)warriorLine.size();for (int i = 0; i < len; ++i)if (warriorLine[i])delete warriorLine[i];}void addWarrior(Warrior* wrr) {warriorLine.push_back(wrr);wrr->warriorBorn();}void clearWarriors() {warriorLine.clear();}void refreshWarriorLine() {//march时调用// erase the dead warriors, then sortfor (auto iter = warriorLine.begin(); iter != warriorLine.end(); ++iter) { //需要考虑到相邻两个武士都死亡的情况while ((*iter)->isDead()) {iter = warriorLine.erase(iter);if (iter == warriorLine.end())break;}if (iter == warriorLine.end())break;}//stable_sort(warriorLine.begin(), warriorLine.end(), &BattleFront::compareWarrior);if (!warriorLine.empty()) {//qsort(warriorLine[0], warriorLine.size(), sizeof(Warrior*), &compareWarrior);sort(warriorLine.begin(), warriorLine.end(), compareWarrior);//注意 sort中使用的compare函数需要满足严格弱序条件}}void lionEscape() {//000:05for (auto iter = warriorLine.begin(); iter != warriorLine.end(); ++iter) {if ((*iter)->warriorType == 3 && (!(*iter)->isDead())) {Lion* lion = dynamic_cast<Lion*>(*iter);//下行转换为派生类对象指针if (lion->loyalty <= 0) {printTime();cout << " " << lion->sideName << " lion " << lion->warriorNum << " ran away" << endl;lion->Die(); //此处手动让lion死亡,其生命值并没有降为0或0以下}}}this->refreshWarriorLine();}bool march() {//000:10bool win = false;   if (warriorLine.empty())return false;//武士前进,lion减少忠诚度,iceman减少生命值for (auto iter = warriorLine.begin(); iter != warriorLine.end(); ++iter) {Warrior* wrr = *iter;if (wrr->side)wrr->location--;//blueelse wrr->location++;//redif (wrr->warriorType == 3) {//lionLion* lion = dynamic_cast<Lion*>(wrr);lion->loyalty -= loyaltyCost;}if (wrr->warriorType == 2) {//icemanwrr->life -= wrr->life / 10;}}this->refreshWarriorLine();//按照从西到东,先红后蓝的顺序输出到达城市(或司令部)、生命值与攻击力,司令部被占领//000:10 red iceman 1 marched to city 1 with 20 elements and force 30//001:10 red iceman 1 reached blue headquarter with 20 elements and force 30for (auto iter = warriorLine.begin(); iter != warriorLine.end(); ++iter) {Warrior* wrr = *iter;printTime();cout << " " << wrr->sideName << " " << wrr->warriorName << " " << wrr->warriorNum;         if (wrr->side == 0 && wrr->location == cityNum + 1) {// red warrior reached blue hqcout << " reached blue headquarter" << " with " << wrr->life << " elements and force " << wrr->ATK << endl;printTime();cout << " blue headquarter was taken" << endl;win = true;}else if (wrr->side == 1 && wrr->location == 0) {//blue warrior reached red hqcout << " reached red headquarter" << " with " << wrr->life << " elements and force " << wrr->ATK << endl;printTime();cout << " red headquarter was taken" << endl;win = true;}else {cout << " marched to city " << wrr->location << " with " << wrr->life << " elements and force " << wrr->ATK << endl;}}return win;}void wolfTakeWeapon() {//000:35if (warriorLine.empty())return;for (auto iter = warriorLine.begin(); iter < warriorLine.end() - 1; ++iter) {Warrior* wrr1 = *iter;Warrior* wrr2 = *(iter + 1);if (wrr1->location == wrr2->location) {if (wrr1->warriorType != 4 && wrr2->warriorType != 4) { ++iter; continue; }//都不是wolf,不抢if (wrr1->warriorType == 4 && wrr2->warriorType == 4) { ++iter; continue; }//都是wolf,也不抢,++iter相当于加两次,跳过了wrr2if (wrr1->warriorType == 4) {Wolf* wolf = dynamic_cast<Wolf*>(wrr1);wolf->takeArm_Wolf(wrr2);++iter;}if (wrr2->warriorType == 4) {Wolf* wolf = dynamic_cast<Wolf*>(wrr2);wolf->takeArm_Wolf(wrr1);++iter;}}}}bool fightEnd(Warrior* red_wrr, Warrior* blue_wrr) {//be sure that wrr1 is red!if (!red_wrr->isDead() && blue_wrr->isDead()) {//red wrr winsprintTime();cout << " " << red_wrr->sideName << " " << red_wrr->warriorName << " " << red_wrr->warriorNum << " killed " <<blue_wrr->sideName << " " << blue_wrr->warriorName << " " << blue_wrr->warriorNum << " in city " << red_wrr->location <<" remaining " << red_wrr->life << " elements" << endl;red_wrr->takeArms(blue_wrr);return true;}else if (red_wrr->isDead() && !blue_wrr->isDead()) {//blue wrr winsprintTime();cout << " " << blue_wrr->sideName << " " << blue_wrr->warriorName << " " << blue_wrr->warriorNum << " killed " <<red_wrr->sideName << " " << red_wrr->warriorName << " " << red_wrr->warriorNum << " in city " << red_wrr->location <<" remaining " << blue_wrr->life << " elements" << endl;blue_wrr->takeArms(red_wrr);return true;}else if (red_wrr->isDead() && blue_wrr->isDead()) {//both diedprintTime();cout << " both red " << red_wrr->warriorName << " " << red_wrr->warriorNum << " and blue " <<blue_wrr->warriorName << " " << blue_wrr->warriorNum << " died in city " << blue_wrr->location << endl;return true;}else {//both aliveif (red_wrr->isHarmless() && blue_wrr->isHarmless()) {//both are harmlessprintTime();cout << " both red " << red_wrr->warriorName << " " << red_wrr->warriorNum << " and blue " <<blue_wrr->warriorName << " " << blue_wrr->warriorNum << " were alive in city " << blue_wrr->location << endl;return true;}else return false;}}void Battle() {//000:40if (warriorLine.empty())return;for (auto iter = warriorLine.begin(); iter < warriorLine.end() - 1; ++iter){Warrior* wrr1 = *iter;Warrior* wrr2 = *(iter + 1);if (wrr1->location == wrr2->location) {//battle starts, wrr1-red wrr2-bluewrr1->refreshArmsUse();wrr2->refreshArmsUse();if (wrr1->location % 2 == 0) {//even number, blue firstwhile (true) {wrr2->fight(wrr1);if (fightEnd(wrr1, wrr2))break;wrr1->fight(wrr2);if (fightEnd(wrr1, wrr2))break;}}else {//odd number, red firstwhile (true) {wrr1->fight(wrr2);if (fightEnd(wrr1, wrr2))break;wrr2->fight(wrr1);if (fightEnd(wrr1, wrr2))break;}}//不确定是先输出完所有战斗结果,再yell;还是按照城市进行if (wrr1->warriorType == 0 && !wrr1->isDead()) {printTime();cout << " red dragon " << wrr1->warriorNum << " yelled in city " << wrr1->location << endl;}if (wrr2->warriorType == 0 && !wrr2->isDead()) {printTime();cout << " blue dragon " << wrr2->warriorNum << " yelled in city " << wrr2->location << endl;}++iter;}}}void reportWarriorStatus() {//000:55if (warriorLine.empty())return;this->refreshWarriorLine();for (auto iter = warriorLine.begin(); iter != warriorLine.end(); ++iter) {Warrior* wrr = *iter;printTime();cout << " " << wrr->sideName << " " << wrr->warriorName << " " << wrr->warriorNum <<" has " << wrr->armCount[0] << " sword " << wrr->armCount[1] << " bomb " << wrr->armCount[2] << " arrow and " <<wrr->life << " elements" << endl;}}
};
BattleFront battlefront;
void Headquarter::makeWarrior() {if (isStopped)return;currWarrior = makingSeq[side][numTotal % 5];     //No. of current warrior 0-dragon 1-ninja 2-iceman 3-lion 4-wolfif (lifeSource >= warrLife[currWarrior]) {      //若当前生命元大于等于武士生命值,可以制造当前武士   lifeSource -= warrLife[currWarrior];       //减少生命元,先于武士降生,因为要根据降生后的生命元来生成士气值和忠诚度numTotal++;        //武士编号,初始为1switch (currWarrior){case 0: //dragonbattlefront.addWarrior(new Dragon(numTotal, side, warrLife[0], warrATK[0], this)); break;//Dragon对象是一个局部对象,赋值给newWarrior的时候只保留了其中属于warrior对象的部分case 1: //ninjabattlefront.addWarrior(new Ninja(numTotal, side, warrLife[1], warrATK[1], this)); break;case 2: //icemanbattlefront.addWarrior(new Iceman(numTotal, side, warrLife[2], warrATK[2], this)); break;case 3: //lionbattlefront.addWarrior(new Lion(numTotal, side, warrLife[3], warrATK[3], this)); break;case 4: //wolfbattlefront.addWarrior(new Wolf(numTotal, side, warrLife[4], warrATK[4], this)); break;}//pWarriors.back()->warriorBorn();return;}else {     //若当前生命元不足以制造当前武士,则停止制造武士isStopped = true;return;}
}
int main() {int n;      //case numbercin >> n;for (int caseNum = 1; caseNum <= n; ++caseNum) {/*输入与初始化*/cin >> lifeAll >> cityNum >> loyaltyCost >> stopTime >>warrLife[0] >> warrLife[1] >> warrLife[2] >> warrLife[3] >> warrLife[4] >>warrATK[0] >> warrATK[1] >> warrATK[2] >> warrATK[3] >> warrATK[4];redHQ.reset(); blueHQ.reset(); //reset headquarter statuscurr_hour = 0;       //set time at 0cout << "Case " << caseNum <<":" << endl;while (true) {curr_minute = 0;if (curr_minute + curr_hour * 60 > stopTime)break;redHQ.makeWarrior(); blueHQ.makeWarrior();//lionrunawaycurr_minute = 5;if (curr_minute + curr_hour * 60 > stopTime)break;battlefront.lionEscape();//marchcurr_minute = 10;if (curr_minute + curr_hour * 60 > stopTime)break;bool winstatus = battlefront.march();if (winstatus)break;//wolftakewaeponcurr_minute = 35;if (curr_minute + curr_hour * 60 > stopTime)break;battlefront.wolfTakeWeapon();//battlecurr_minute = 40;if (curr_minute + curr_hour * 60 > stopTime)break;battlefront.Battle();//reportpowercurr_minute = 50;if (curr_minute + curr_hour * 60 > stopTime)break;redHQ.reportLifeSource(); blueHQ.reportLifeSource();//reportstatuscurr_minute = 55;if (curr_minute + curr_hour * 60 > stopTime)break;battlefront.reportWarriorStatus();++curr_hour;}battlefront.clearWarriors();}return 0;
}

致谢

感谢这些文章,真的帮了我很大的忙!好人一生平安.jpg
c++ invalid comparator
北京大学MOOC 程序设计与算法(三)魔兽世界三(开战)
dynamic_cast用法总结
OpenJudge - 045:魔兽世界三(开战) ←提供了错误测试点输入输出

真是赏心悦目的颜色呢

E:魔兽世界三(开战) 2022春季程设实习相关推荐

  1. 北京大学MOOC 程序设计与算法(三)魔兽世界三(开战)

    魔兽世界三(开战) 题目来源 北京大学MOOC 程序设计与算法(三)魔兽世界3(2020秋季) 题目描述 魔兽世界三(开战) 总时间限制: 2000ms 内存限制: 65536kB 魔兽世界的西面是红 ...

  2. 编程作业--魔兽世界三(开战)

    魔兽世界三(开战) 描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部.两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 .... N ( N <= 20).红魔军的 ...

  3. 045:魔兽世界三(开战) 程序设计实习MOOC / 程序设计与算法(三)测验题汇总(2020春季) 已经结束

    总时间限制: 2000ms 内存限制: 65536kB 描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部.两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 - N ( N ...

  4. 045:魔兽世界三(开战) + 自己思路及代码

    北大mooc,程序设计与算法(三) 题目 描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部.两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 - N ( N <= ...

  5. 18.04.06 魔兽世界三(开战)

    描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部.两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 .... N ( N <= 20).红魔军的司令部算作编号为0的 ...

  6. 信号与系统分析2022春季作业-参考答案:第三次作业-第一部分

      封面动图来自于: SHUTTERSTOCK网站 §00 作业题目   作业要求链接: 信号与系统 2022 春季学期第三次作业 https://zhuoqing.blog.csdn.net/art ...

  7. 程设大作业之魔兽世界

    [前言]:在学习了一些看上去只是能让程序更好看更清晰的类的知识之后...为了让我们真的觉得类是个好东西,丧心病狂的作业--魔兽出现了...然而...emmmm... 好吧,这篇博客主要就是记录一下自己 ...

  8. 航空航天大类C语言程设第三次练习赛

    航空航天大类C语言程设第三次练习赛 第四期更新, 鸽子博主终于更新第三次练习赛了 (A题)求区间交并集 多行数据,每行有两个数,用空格分开,表示每个区间的下和上界,保证是合法的非空集,而且得到的并集是 ...

  9. 高端专业运动品牌迪桑特推出2022春季女子运动系列

    上海2022年2月25日 /美通社/ -- 高端专业运动品牌DESCENTE迪桑特正式推出2022春季女子运动系列,包含TRAINING综训.A-MOTION动量生活和STUDIO灵感型动三大子系列. ...

最新文章

  1. Java 8新特性——default方法(defenece方法)介绍
  2. go 链路追踪_【go-micro实践】jaeger分布式链路追踪
  3. 4. 分类的线性模型
  4. java网络编程Socket中SO_LINGER选项的用法解读
  5. (总结)Linux下多行合并成一行,中间加分隔符
  6. 已有项目要不要迁移到Addressable系统?
  7. 二、Linux系统目录和文件基本操作
  8. 我构建应用的这十年......
  9. 电脑可以开机但是黑屏_铅锤哥:十五种电脑开机黑屏的原因与解决思路
  10. android反编译工具mercury_JAVA反编译工具集锦
  11. pythontuple数据类型_Python数据类型之Tuple元组实例详解
  12. redux-chunk中间件的安装和使用-(二)
  13. U盘镜像刻录(制作U盘启动盘)
  14. j2me之诺基亚S40模拟器
  15. 实现原理 扫描枪_条码扫描枪的工作原理
  16. React native和原生之间的通信
  17. python+selenium实现网页全屏截图
  18. c语言答案-贾宗璞 许合利,c语言程序设计答案贾宗璞许合利
  19. 2023年湖北助理工程师在哪里申报?助理工程师的五大作用你知道吗
  20. 使用Pycharm关于自定义模块库的安装如douyin模块

热门文章

  1. 注意:10种新人最让前辈讨厌
  2. 投资组合的风险因子调整——投资组合分析(EAP.portfolio_analysis)
  3. SQL SERVER EXEC 、SP_EXECUTESQL
  4. 360手机品牌发布会都玩了些什么?
  5. DHCP和路由动态协议
  6. 机器学习和数据科学的最佳公共数据集机器学习、数据科学、情感分析、计算机视觉、自然语言处理 (NLP)、临床数据等的最佳公共数据集。
  7. 跨越40多年的“以太”风云,了解一下?
  8. 从一台Linux服务器访问另一台Linux服务器
  9. iOS安全逆向之旅--安全逆向环境搭建和工具使用介绍
  10. 会声会影添加遮罩教程