c++魔兽世界1_备战

2019-04-02  本文已影响0人  m_阿飞

魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市。
红司令部,City 1,City 2,……,City n,蓝司令部
两军的司令部都会制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值、攻击力这三种属性。
双方的武士编号都是从1开始计算。红方制造出来的第n个武士,编号就是n。同样,蓝方制造出来的第n个武士,编号也是n。
武士在刚降生的时候有一个生命值。
在每个整点,双方的司令部中各有一个武士降生。
红方司令部按照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 headquarte
    表示在4点整,编号为5的蓝魔lion武士降生,它降生时生命值为5,降生后蓝魔司令部里共有2个lion武士。(为简单起见,不考虑单词的复数形式)注意,每制造出一个新的武士,都要输出此时司令部里共有多少个该种武士。
  2. 司令部停止制造武士
    输出样例: 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
000 blue lion 1 born with strength 6,1 lion in blue headquarter
001 red lion 2 born with strength 6,1 lion in red headquarter
001 blue dragon 2 born with strength 3,1 dragon in blue headquarter
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
003 red headquarter stops making warriors
003 blue iceman 4 born with strength 5,1 iceman in blue headquarter
004 blue headquarter stops making warriors

我的思路是定义一个叫knight的类。里面定义knight的指针,红蓝方的战士出场顺序,总生命值,最小生命值,随时间产生的英雄(单个种类英雄数量)等。下面附上knight类的数据成员和成员函数

#pragma once
#include <iostream>
#include <string>
class knight
{
private:
    knight *base;                                   //定义一个指向knight型的指针;
    std::string red_name[5] ;                   //红方战士出场顺序名字
    std::string blue_name[5];                   //蓝方战士出场顺序名字
    int m_min_knight = 10000;               //最小的战士生命值  
    int m_redskip=0;                                //红方跳过英雄的个数
    int m_blueskip=0;                               //蓝方跳过英雄的个数
    int m_redknight_allnum = 0;             //红方战士总个数
    int m_blueknight_allnum = 0;            //蓝方战士总个数
    int m_allvitality;                              //总生命力
    int m_redvitality[5];                           //5个红色战士各自生命值
    int m_bluevitality[5];                          //5个蓝色战士各自生命值
    int *m_arr_redskip;                         //定义一个指针指向的红色(跳过数组)存放因生命值不足而跳过的红方英雄
    int *m_arr_blueskip;                            //定义一个指针指向的蓝色(跳过数组)存放因生命值不足而跳过的蓝方英雄
    int *m_arr_rednumber;                       //定义一个指针指向的红方单个种类英雄数量(对应编号)第七列;
    int *m_arr_bluenumber;                  //定义一个指针指向的蓝方单个种类英雄数量(对应编号)第七列;
public:
    void set_sum(int vitality, int &knight_allnum, int single_vitality[], int *&num, int *&Skip,int &skip);//计算红蓝战士总数目及跳过的总个数
    void set_num(int vitality, int single_vitality[], int *&num, int *&Skip);//根据时间段的战士单个数目,把因生命值不足生产而跳过的放入(跳过数组)。
    void set_knight(int p[],int Vitality);                          //设置红蓝方战士生命值序列。第一个参数为各个生命数组,第二个参数总的生命值,第三,四个参数用于设置战士个数数组和跳过数组,动态分配内存
    ~knight();
    void dis_time(int);                                                     //显示时间
    void disall(int allnum, int vitality[],int number[],std::string r, std::string color_name[], int i, int num);//根据参数显示蓝方或红方的所有信息
    void dis();//显示基地对象的红蓝方所有英雄的信息
    bool m_decide_skip(int *skip, int i,int allskip);       //判断当前参数i,是否为红方或蓝方的(跳过数组)的值
    int *m_get_arr_redskip();                                       //返回红方的(跳过数组)
    int * m_get_arr_blueskip();                                 //返回蓝方的(跳过数组)
    int * m_get_arr_rednumber();                                //返回红方战士编号对应战士数量的数组
    int * m_get_arr_bluenumber();                               //返回蓝方战士编号对应战士数量的数组
};

接下来是knight的成员函数:

#include "knight.h"
#include <iostream>
#include <string>
using namespace std;
void knight::set_knight(int p1[], int Vitality)                                     //获取最小生命值,分别对红蓝英雄生命初始化
{
    for (int i = 0; i<5; i++)
    {
        if (m_min_knight>p1[i])
            m_min_knight = p1[i];                                                           //得到英雄最小生命值
    }
        m_allvitality = Vitality;
        m_redvitality[4] = m_bluevitality[1] = p1[0];                               //根据红蓝方出场顺序,初始化英雄血量
        m_redvitality[3] = m_bluevitality[2] = p1[1];
        m_redvitality[0] = m_bluevitality[3] = p1[2];
        m_redvitality[1] = m_bluevitality[0] = p1[3];
        m_redvitality[2] = m_bluevitality[4] = p1[4];
        int skip_red = 0, skip_blue = 0;                                                        //用于(跳过数组)的下标
        set_sum(m_allvitality, m_redknight_allnum, m_redvitality, m_arr_rednumber, m_arr_redskip, m_redskip);
        set_sum(m_allvitality, m_blueknight_allnum, m_bluevitality, m_arr_bluenumber, m_arr_blueskip, m_blueskip);
        set_num(m_allvitality, m_redvitality, m_arr_rednumber, m_arr_redskip);
        set_num(m_allvitality, m_bluevitality, m_arr_bluenumber, m_arr_blueskip);
}
void knight::set_num(int vitality, int single_vitality[], int *&M_number,int *&M_skip)
{
    int skip_color = 0;
    for (int i = 0,num = 0; vitality >= m_min_knight; i++, num++)
    {   
        if (i == 5)
            i = 0;
        if (vitality >= single_vitality[i])                                             //当总生命值大于要制造英雄生命
        {
            if (num < 5)
                M_number[num] = 1;                                                  //单个种类英雄加1(对应编号)
            else
                M_number[num] = M_number[num - 5] + 1;          //单个种类英雄加1(对应编号)
            vitality -= single_vitality[i];                                             //减少总生命值
        }
        else
        {
            M_skip[skip_color] = num;
            skip_color++;
            continue;
        }
    }
}
void knight::set_sum(int vitality, int &knightallnum, int single_vitality[], int * &num, int * &Skip, int &skip)
{
    int knight_allnum = 0;
    int skip_color = 0;
    for (int i = 0, code = 0, num = 0; vitality >= m_min_knight; i++, num++)
    {
        knight_allnum++;                                                            //英雄总量
        if (i == 5)
            i = 0;
        if (vitality >= single_vitality[i])                                             //当总生命值大于要制造英雄生命
        {
            code++;
            vitality -= single_vitality[i];                                             //减少总生命值
        }
        else
        {
            skip_color++;
            continue;
        }
    }
    skip = skip_color;
    knightallnum = knight_allnum;
    num = new int[knightallnum];
    Skip = new int[skip];
}

void knight::dis_time(int i)                                                                //  设置时间
{
    using std::cout;
    if (i >= 0 && i<10)
        cout << "00" << i << " ";
    else if (i >= 10 && i<100)
        cout << "0" << i << " ";
    else if (i>=100)
        cout << i<<" ";
}
void knight::disall(int allnum, int vitality[],int number[], std::string color, string color_name[], int i, int num)
{
    dis_time(num);                                                                                                          //显示时间
        int  z = i;
        if (i >4)
            z = i % 5;
        if (i==allnum)                                                                                                      //结束语句
        cout << color << "headquarter stops making warriors" << endl;
        else
        {
            cout << color << " " << color_name[z] 
                    << " " << num + 1 << " born with strength "
                    <<vitality[z] << ","
                    << number[i] << " " 
                    << color_name[z] << "in " 
                    << color << " headquarter " << endl;
        }   
}
void knight::dis()
{
    int time;
    int sum = m_redknight_allnum>m_blueknight_allnum ? m_redknight_allnum : m_blueknight_allnum;        //取红蓝方英雄中的最大值
    int skip_red = 0, skip_blue = 0,other=0;
    for (int red_i = -1,blue_i=-1; red_i < sum &&blue_i<sum;)
    {
        if (red_i < m_redknight_allnum&&other == 0)     //other的作用是避免一个时间点,只输出一种颜色的战士信息
        {                                                                           //当输出红方后,如果蓝方刚好跳过,下一轮不不输出红方,继续输出蓝方
            red_i++;
            if (m_decide_skip(m_arr_redskip, red_i,m_redskip))                                      //判断是否有跳过的
            {
                skip_red++;                         //累计跳过次数
                continue;
            }
            time = red_i - skip_red;
            disall(m_redknight_allnum, m_redvitality,m_arr_rednumber,"red", red_name, red_i,time);
        }
        if (blue_i< m_blueknight_allnum)
        {
            blue_i++;
            if (m_decide_skip(m_arr_blueskip, blue_i, m_blueskip))                                      //判断是否有跳过的
            {
                skip_blue++;                                                                                        //累计跳过次数
                other = 1;
                continue;
            }

            time = blue_i - skip_blue;
            disall(m_blueknight_allnum, m_bluevitality, m_arr_bluenumber, "blue", blue_name, blue_i, time);
            other = 0;
        }
    }
}
bool knight::m_decide_skip(int *skip,int i,int allskip)                                 //判断是否有跳过的出生的英雄
{
    int skip_2 = 0;                                                         
    for (int s = 0; s < allskip; s++)
    if (i == skip[s])
    {
        skip_2 = 1;
        break;
    }
    if (skip_2 == 1)
        return true;
    else
        return false;
}

knight::~knight()
{
    delete []base;
}


int *knight::m_get_arr_redskip()
{
    return m_arr_redskip;
}

int *knight::m_get_arr_blueskip()
{
    return m_arr_blueskip;
}
int *knight::m_get_arr_rednumber()
{
    return m_arr_rednumber;
}
int *knight::m_get_arr_bluenumber()
{
    return m_arr_bluenumber;
}

最后是main函数

#include <iostream>
#include <string>
#include <stdlib.h>
#include "knight.h"
using namespace std;
int main()
{
    string r = ("red");
    string b = ("blue");
    string red_name[5] = { "iceman", "lion", "wolf ", "ninja", "dragon " };     //红方英雄出场顺序
    string blue_name[5] = { "lion", "dragon ", "ninja", "iceman", "wolf " };    //蓝方英雄出场顺序
    string knight_name[5] = { "dragon", "ninja", "iceman", "lion", "wolf" };
    int t_all_vitality , t_vitality[5];
    int sample = 0;
    cin >> sample;                                  //输入要测试的数据数量
    knight *base = new knight[sample];                                  //                                                              //  for (int i = 0; i <sample; i++)
    {
        cin >> t_all_vitality;                                          //输入城市总的生命值;
        for (int i = 0; i < 5; i++)
            cin >> t_vitality[i];                                       //输入各个战士的生命值;
        base[i].set_knight(t_vitality, t_all_vitality);     //获取最小生命值,分别对红蓝英雄生命初始化
    }
    for (int i = 0; i <sample; i++)
    {
        cout << "Case: "<< i+1<< endl;
        base[i].dis();
    //  delete []base;  //是删除所有base对象,会导致程序崩溃,显示不出后面Case内容
        delete [](base[i].m_get_arr_bluenumber());
        delete [](base[i].m_get_arr_rednumber());
        delete [](base[i].m_get_arr_blueskip());
        delete [](base[i].m_get_arr_redskip());
    }
    delete[]base;
    system("pause");
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读