C++ 魔兽世界之二:装备
总时间限制: 1000ms 内存限制: 65536kB
描述
魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市。
红司令部,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分开始到双方司令部停止制造武士为止的所有事件按顺序输出。
一共有两种事件,其对应的输出样例如下:
- 武士降生
输出样例: 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。 - 司令部停止制造武士
输出样例: 010 red headquarter stops making warriors
表示在 10点整,红方司令部停止制造武士
输出事件时:
首先按时间顺序输出;
同一时间发生的事件,先输出红司令部的,再输出蓝司令部的。
输入
第一行是一个整数,代表测试数据组数。
每组测试数据共两行。
第一行,一个整数M。其含义为: 每个司令部一开始都有M个生命元( 1 <= M <= 10000)
第二行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它们都大于0小于等于10000
输出
对每组测试数据,要求输出从0时0分开始,到双方司令部都停止制造武士为止的所有事件。
对每组测试数据,首先输出“Case:n" n是测试数据的编号,从1开始
接下来按恰当的顺序和格式输出所有事件。每个事件都以事件发生的时间开头,时间以小时为单位,有三位。
样例输入
1
20
3 4 5 6 7
样例输出
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
相比较备战,这次的武士多出了个性,故每种武士不单单是一个名字,需要从武士类派生定制个性;
需要在派生出的武士类中添加该派生类的武器即可。
武士 分为5种
武器 分为 swor、bomb 、arrow 三种
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
#define WARRIOR_NUM 5 //武士数
#define WEAPON_NUM 3 //武器数
#define MAX_WARRIORS 1000 //武士最大数量enum { DRAGON,NINJA,ICEMAN,LION,WOLF}; //枚举,即dragon=0,ninja=1,2,3,4
武器类的定义
武器有序号——0-2
武器有攻击力——本题未定义
静态变量——与武器类相关的全局变量,分别为武器的攻击力列表,武器名字的列表
均可由武器的序号得到
class CWeapon
{public:int nKindNo; //序号 int nForce; //攻击力static int InitialForce[WEAPON_NUM]; //武器初始攻击力列表 static const char *Names[WEAPON_NUM]; //武器名字的列表
};
武士类的定义
武士的属性:所属司令部颜色,所拥有生命值,所拥有武器,种类名,序号
武士的制造顺序与基地的颜色有关
武士的制造结束与基地的生命值有关
故需要指向基地的指针,得到基地的有关参数
class CHeadquarter; //声明司令类
class CWarrior{ protected: //保护,派生可以访问当前对象的protect内容 CHeadquarter *pHeadquarter; //指向该武士基地的指针,用于得到基地的颜色,基地的生命值 int nNo; //武士的编号,用于武士计数 public:static const char*Names[WARRIOR_NUM]; //静态数组——武士名字static int InitialLifeValue[WARRIOR_NUM]; //静态数组——每种武士的初始生命值CWarrior(CHeadquarter * p, int nNo_); //武士构造函数——输入基地指针,武士编号virtual void PrintResult(int nTime,int nKindNo); //虚函数——输出函数——此为通用输出函数 virtual void PrintResult(int nTime) =0; //虚函数——输出函数———此为派生类的个性输出函数virtual ~CWarrior(){} //虚函数——析构函数
};
司令类的定义
司令类的有颜色和生命值两个属性;
为输出服务的成员:
为判断能否继续生产武士,添加stop成员;
要输出每种武士的个数,故需要anWarriorNum列表,记录每种武士的个数;
需要确定当前制造武士的种类,可由武士总数/循环个数得出;
需要列表保存以生产的每一个武士,方便进行后续处理;
class CHeadquarter //定义司令部
{private:int nTotalLifeValue; //基地总生命值 bool bStopped; //是否停止制造 int nColor; //基地颜色 int nCurMakingSeqIdx; //当前正在制造的武士序列号int anWarriorNum[WARRIOR_NUM]; //每种武士的数量 int nTotalWarriorNum; //总武士数量 CWarrior * pWarriors[MAX_WARRIORS]; public:friend class CWarrior; //友元武士,武士类可访问司令类private static int MakingSeq[2][WARRIOR_NUM]; //制作顺序表,void Init(int nColor_, int lv); //声明初始函数——颜色,生命值~CHeadquarter(); //声明析构函数int Produce(int nTime); //声明生产函数,需要输入当前时间void GetColor(char * szColor); //声明函数,得到当前基地的颜色 int GetTotalLifeValue() { return nTotalLifeValue;} //声明函数,得到当前基地的生命值
};
派生类的定义
class CDragon:public CWarrior{ //武士派生
//dragon 拥有武器和士气
//武器:编号为n%3,n为dragon的编号
//士气:降生后司令部剩余生命元的数量除以造dragon所需的生命元数量,double类型private:CWeapon wp; //武器 double fmorale; //忠诚度public:void Countmorale(){ //指向司令部的指针——得到司令部的生命值 fmorale = pHeadquarter -> GetTotalLifeValue()/(double)CWarrior::InitialLifeValue[0]; //序号0为dragon } CDragon( CHeadquarter *p, int nNo_): CWarrior(p,nNo_){ //初始构造函数,基类有的与基类相同 wp.nKindNo = nNo % WEAPON_NUM; //武器种类构造 wp.nForce = CWeapon::InitialForce[wp.nKindNo]; //攻击力数值构造 Countmorale(); //士气构造 }void PrintResult(int nTime) //虚函数{CWarrior::PrintResult(nTime,DRAGON); //调用基类的printresult printf("It has a %s,and it's morale is %.2f\n",CWeapon::Names[wp.nKindNo],fmorale); //Dragon类特有的输出 }
};
class CNinja:public CWarrior
{private:CWeapon wps[2]; //派生出2把武器 public:CNinja(CHeadquarter *p, int nNo_): CWarrior(p,nNo_) //得到基类的构造 { //添加武器的构造方法 wps[0].nKindNo=nNo%WEAPON_NUM; //确定武器序号 wps[0].nForce = CWeapon::InitialForce[wps[0].nKindNo]; //确定武器攻击力 wps[1].nKindNo=(nNo+1)%WEAPON_NUM;wps[1].nForce = CWeapon::InitialForce[wps[1].nKindNo]; //武器类里的该种武器的攻击力 }void PrintResult(int nTime) //输出函数 {CWarrior::PrintResult(nTime,NINJA); //此处NINJA为开头的序号 ,先调用武士类的print函数 printf("It has a %s and a %s\n",CWeapon::Names[wps[0].nKindNo],CWeapon::Names[wps[1].nKindNo]);//再输出两把武器的名字 } };
class CIceman:public CWarrior{private:CWeapon wp;public:CIceman(CHeadquarter * p, int nNo_):CWarrior(p,nNo_) //构造函数{wp.nKindNo=nNo % WEAPON_NUM;wp.nForce=CWeapon::InitialForce[wp.nKindNo];} void PrintResult(int nTime){CWarrior::PrintResult(nTime,ICEMAN);printf("It has a %s\n",CWeapon::Names[wp.nKindNo]); //输出该武士的武器 }
};
class CLion:public CWarrior
{private:int nLoyalty; //忠诚度public:void CountLoyalty() //定义函数,得到nloyalty {nLoyalty=pHeadquarter->GetTotalLifeValue();} CLion(CHeadquarter *p, int nNo_):CWarrior(p,nNo_){ //构造函数——调用父类 CountLoyalty(); //赋值nloyalty } void PrintResult(int nTime){CWarrior::PrintResult(nTime,LION);CountLoyalty();printf("It's loyalty is %d\n",nLoyalty);}
};
class CWolf:public CWarrior{public:CWolf(CHeadquarter *p, int nNo_): CWarrior(p,nNo_){} //构造函数,与父类完全相同 void PrintResult(int nTime) {CWarrior::PrintResult(nTime,WOLF); //print函数,与父类相同 }
};
补充武士类的内部函数
1.构造函数
CWarrior::CWarrior(CHeadquarter *p,int nNo_) //武士类构造函数
{nNo=nNo_;pHeadquarter =p;
}
2.输出函数
制造该武士的时间
输出该武士的司令部颜色
武士的序号,
武士的种类,
武士种类的个数——该属性保存司令部中
武士的生命值;
void CWarrior::PrintResult(int nTime, int nKindNo) //双参数的武士类print函数
{ //要输出的时间数,武士的种类 char szColor[20]; pHeadquarter->GetColor(szColor); //得到当前司令部颜色,防暑szColor中 printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n",nTime,szColor,Names[nKindNo],nNo,InitialLifeValue[nKindNo],pHeadquarter->anWarriorNum[nKindNo],Names[nKindNo],szColor);
}
补充司令部的内部函数
1.司令部初始化函数
void CHeadquarter::Init(int nColor_, int lv) //司令部初始化函数
{nColor= nColor_;nTotalLifeValue = lv;bStopped = false; nCurMakingSeqIdx=0; nTotalWarriorNum=0; for(int i=0;i<WARRIOR_NUM;i++)anWarriorNum[i]=0;
}
2.司令部析构函数
因pWarrior为动态数组,结束后需要全部释放
CHeadquarter::~CHeadquarter(){ //司令部析构函数 int i;for (i=0;i<nTotalWarriorNum;i++)delete pWarriors[i]; //删除武士类列表的信息
}
3.制造函数
用于判断能否制造武士,和输出制造出的武士
先判断停止条件——每一个武士都无法制造
(1)当前武士无法制造,则看下一个武士能否制造,直到看完全部武士
(2)跳出上述循环,依旧无法制造,则返回停止
(3)上述条件不满足,说明可以制造,则开始制造
制造武士
(1)确定武士种类——通过curMakingSeqIdx得到当前制造武士的种类
(2)由种类确定武士生命值,由武士总数确定当前武士序号,由每种武士个数确定武士的种内序号
(3)基地生命值-=武士生命值
(4)为制造下一个武士做准备
(5)将当前武士保存至勇士列表,利用多态性质调用每种武士的输出函数;
int CHeadquarter::Produce(int nTime) //制造函数
{int nSearchingTimes=0;if(bStopped) //停止标记 return 0;while(CWarrior::InitialLifeValue[MakingSeq[nColor][nCurMakingSeqIdx]]>nTotalLifeValue&& nSearchingTimes<WARRIOR_NUM) //当前正在造的武士(由基地颜色和制造序号确定)生命值大于基地生命值 { //且未遍历完每一个武士 nCurMakingSeqIdx=(nCurMakingSeqIdx+1)%WARRIOR_NUM;nSearchingTimes ++; //查找次数也+1——到5个后停止查找并弹出结束 } //跳出上述循环时 int nKindNo=MakingSeq[nColor][nCurMakingSeqIdx]; //得到当前要造的武士的序号if(CWarrior::InitialLifeValue[nKindNo]>nTotalLifeValue) //说明遍历完了每一个武士,都不能造,故停止制造 {bStopped=true; //停止标记 if(nColor==0) //按基地颜色输出 printf("%03d red headquarter stops making warriors\n",nTime);else printf("%03d blue headquarter stops making warriors\n",nTime);return 0;} //说明可以制造武士 nTotalLifeValue -= CWarrior::InitialLifeValue[nKindNo]; //基地总生命值-所制造武士生命值 nCurMakingSeqIdx = (nCurMakingSeqIdx+1)%WARRIOR_NUM; //制造武士序列+1 int nTmp= anWarriorNum[nKindNo]; //得到当前种类武士的已有数量anWarriorNum[nKindNo]++; //+1switch(nKindNo){case DRAGON: //DRAGON=1pWarriors[nTotalWarriorNum] = new CDragon(this,nTotalWarriorNum+1); //生成动态对象,放入武士列表 break;case NINJA:pWarriors[nTotalWarriorNum]= new CNinja(this, nTotalWarriorNum+1); //this为当前基地对象,武士编号break;case ICEMAN:pWarriors[nTotalWarriorNum]= new CIceman(this, nTotalWarriorNum+1);break;case LION:pWarriors[nTotalWarriorNum]= new CLion(this,nTotalWarriorNum+1);break;case WOLF:pWarriors[nTotalWarriorNum]= new CWolf(this,nTotalWarriorNum+1);break;} pWarriors[nTotalWarriorNum]->PrintResult(nTime); //用多态——调用了当前武士对象的printresult函数 nTotalWarriorNum ++; //总武士数+1 return 1;}
司令部类的颜色函数
将int转化为颜色str
void CHeadquarter::GetColor(char * szColor) //定义getcolor函数 {if(nColor==0) //0红,1蓝 strcpy(szColor,"red");elsestrcpy(szColor,"blue");}
静态变量的初始化
const char * CWeapon::Names[WEAPON_NUM] = {"sword","bomb","arrow"}; //武器列表
int CWeapon::InitialForce[WEAPON_NUM]; //武器的攻击力列表——这次未用到const char *CWarrior::Names[WARRIOR_NUM] = {"dragon","ninja","iceman","lion","wolf"}; //武士列表 int CWarrior::InitialLifeValue[WARRIOR_NUM]; //武士总生命值列表int CHeadquarter::MakingSeq[2][WARRIOR_NUM] = {{2,3,4,1,0},{3,0,1,2,4}}; //红蓝方制造武士的顺序
主函数
int main(){int t; //case个数int m; //基地生命值CHeadquarter RedHead,BlueHead;scanf("%d",&t);int nCaseNo=1; //当前case数while(t--){printf("Case:%d\n",nCaseNo++);scanf("%d",&m); //读入生命值总数 int i;for (i=0;i<WARRIOR_NUM;i++)scanf("%d", &CWarrior::InitialLifeValue[i]); //读入每个武士的生命值// for(i=0;i<WEAPON_NUM;i++)// scanf("%d",&CWeapon::InitialForce[i]); //读入每把武器的攻击力 RedHead.Init(0,m); //颜色,生命值 BlueHead.Init(1,m);int nTime=0;while(true){int tmp1=RedHead.Produce(nTime); //调用produce即出现输出int tmp2=BlueHead.Produce(nTime);if(tmp1==0 && tmp2==0) //生产结束break; //停止循环nTime ++;}}return 0;
}
C++ 魔兽世界之二:装备相关推荐
- POJ C++程序设计 编程题#2 魔兽世界之二:装备
编程题#2: 魔兽世界之二:装备 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB ...
- C++ 程序设计 week5 魔兽世界二: 装备
编程题#2: 魔兽世界之二:装备 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB ...
- 开源项目 OpenJudge-3:魔兽世界之二:装备
开源项目 OpenJudge-3:魔兽世界之二:装备 程序说明文档 Github地址 项目主要使用的技术: MVC模式.单例模式.继承与多态.虚函数.STL库.文件流.I/O流.字符串流.智能指针.g ...
- 北大C++课后题系列:022:魔兽世界之二:装备
C++ 022:魔兽世界之二:装备 北大程序设计与算法(三) 描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部.两个司令部之间是依次排列的若干城市. 红司令部,City 1,City 2,- ...
- C++面向对象程序设计 021:魔兽世界之二:装备 ---- (北大Mooc)
文章目录 专题博客链接 前引 他人博客优秀代码 我的代码(提交过不了 但是数据本地测试正常 一行一行的进行了对比 都不知道为什么AC不了) 闲聊 专题博客链接 北大C++ POJ课后习题博客全解记录 ...
- 程设作业:魔兽世界2:装备
直接贴代码: #include <vector> #include <iostream> #include <iomanip> #include <strin ...
- 021:魔兽世界之二:装备
题目: http://cxsjsxmooc.openjudge.cn/2021t3springall2/021/ 分析: 本题主要是在 " 魔兽世界之一 " 的基础上增加了装备系统 ...
- 北大程序设计实习MOOC 编程作业 《魔兽世界之二:装备》
这次作业是在第一次的基础上完成的,主要要求是完成五种武士的封装.这五种武士的特性(相应类的成员变量)不大相同,但可以从同一个基类派生.随着时间变化,生成相应的武士,并输出相关信息.OJ地址为:这里 解 ...
- MOOC编程题#2: 魔兽世界之二:装备
描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部.两个司令部之间是依次排列的若干城市. 红司令部,City 1,City 2,--,City n,蓝司令部 两军的司令部都会制造武士.武士一共 ...
最新文章
- 重磅!如何高效学习单目深度估计
- 2020年学什么计算机软件,2020年大学计算机软件专业排行榜
- 数据结构与算法,每日一道
- 《数据结构与算法分析—Java语言描述》pdf
- 放大器的传递函数_保证放大器的稳定性什么最重要?反馈电阻一定要选对!
- 前端学习(3186):ant-design的button介绍按钮属性
- Mysql 零距离-入门(二)
- Nodejs cluster模块深入探究
- Graphics.TranslateTransform设置旋转角度不起作用?
- 送给python新手关于pip用法和虚拟环境用法的介绍(英文)
- ASP.NET 数据绑定操作
- LoadRunner 常用C语言函数使用举例说明
- 图解:卷帘快门(Rolling shutter)与全局快门(global shutter)的区别
- Ubuntu安装LXDE桌面环境
- bootstrap地址选择(全国省市选择、定位)功能
- c语言习题---(if语句)
- 计算机基础知识 JAVA基础知识
- PMO项目经理必备的简洁解决问题方案和报告模板
- 内核定制与编译准备工作
- Preface|前言