PKU MOOC作业魔兽世界之一:备战的结构化程序

一不小心踏入PKU程序设计专项课程,没先听课就交钱加入。这门课,目的是培养程序员,从0基础,到程序设计员的培养,课程顺序是C语言-算法-数据结构,实际拆分为6+1门(毕业项目),理念不可谓不好。但是,效果了了。最大的问题,就是这门专项课程,很大部分都是学生自学,课堂互动性几乎为0,没有别的MOOC课程的答疑讨论,只有一些民间自行组织的QQ群。程序设计这东西,零基础入门还是有点勉强。天才是有,更多靠的是勤奋积累。君不见为了进谷歌等大型IT企业,多少人硬是把各种算法、数据结构背了个遍。
今天要说的是PKU这门课中的C++部分的大作业,魔兽世界的第一部分,据说其第三部分终结版非常之变态,代码2k行。这个第一部分,初看起来就觉得很复杂,下面给出题目。

描述

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

红司令部,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 headquarter

表示在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

光看到这一大片,很多人就不想看了。而同一部分作业,上一题是这样的

下面程序的输出是:
10
请补足Sample类的成员函数。不能增加成员变量。

#include <iostream>
using namespace std;
class Sample{
public:
    int v;
    Sample(int n):v(n) { }
// 在此处补充你的代码
};
int main() {
    Sample a(5);
    Sample b = a;
    cout << b.v;
    return 0;
}

这两题根本不是一个量级的,却放在了一起。说是这样,但是不做这一题还过不了,过不了钱就白交了。好吧。c++初学,类还掌握的皮毛,用最原始结构程序方法看能否解决。从输出入手,虽然程序的描述很复杂,但是输出挺简单的。主要有几点:

  • 第一点是输入的变量,这个很简单,其中有一点注意是要求要输入n组cases,之后要把所有用到的变量清零。
  • 第二点是有一个“时钟”,直接每次加1即可
  • 第三点是部队的颜色区别:红色、蓝色;5种战士;战士的编号,计数到生产结束为止;战士的数量。
  • 第四点比较坑爹,就是战士的“强度”怎么理解,后来看仔细检查发现所谓强度就等于战士初始的生命值。并且这个生命值输入的顺序,很红队,蓝队里的顺序三者完全不同
  • 第五点是循环判断,就是说如果当前生产不了,就顺延一位,如果到了队尾还得从头枚举,如果都不行,就停止生产。这里这个终止条件挺绕的,我还没总结出比较简洁完善的写法。

类是应该学好的,因为使用类结构的好处就是,程序方便修改和扩充。但是理解上还有编写上比较困难。结构化程序的好处是,小规模的程序很好理解和编写,缺点就是不好修改很扩充。下面是我写的魔兽备战结构化程序。

#include <iostream>
#include <iomanip>
using namespace std;
int count_red[5]={0};        /*实际每种生产的战士数量*/
int count_blu[5]={0};

int main()
{
    int C=0;       /*cases*/
    int M[2]={0};       /*生命元*/
    int HP[5]={0}; /*战士初始生命*/
    int clock=0;   /*时钟*/
    char color[2][5]={
        "red",
        "blue"
    };               /*军队颜色*/
    char soldier_red[5][8]={/*红队战士种类*/
        "iceman",
        "lion",
        "wolf",
        "ninja",
        "dragon"
    };
    int HP_red[5]={0};       /*真正的红队初始生命*/
    char soldier_blu[5][8]={/*蓝队战士种类*/
        "lion",
        "dragon",
        "ninja",
        "iceman",
        "wolf"
    };
    int HP_blu[5]={0};      /*真正的蓝队初始生命*/

    /*输入*/
    cin>>C;
    for(int j=0;j<C;j++){
        cin>>M[0];
        M[1]=M[0];           /*2队生命元*/
        for(int i=0;i<5;i++){
            cin>>HP[i];          /* dragon 、ninja、iceman、lion、wolf 的初始生命值*/
        }

        /*分配初始生命*/
        /*红队*/
        HP_red[0]=HP[2];
        HP_red[1]=HP[3];
        HP_red[2]=HP[4];
        HP_red[3]=HP[1];
        HP_red[4]=HP[0];
        /*蓝队*/
        HP_blu[0]=HP[3];
        HP_blu[1]=HP[0];
        HP_blu[2]=HP[1];
        HP_blu[3]=HP[2];
        HP_blu[4]=HP[4];

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

    蓝方司令部按照lion、dragon、ninja、iceman、wolf的顺序循环制造武士。*/
        int k=0;
        int pos1=0;       /*红战士定位*/
        int pos2=0;       /*蓝战士定位*/
        int flag_r=0;                        /*红队停止生产标志*/
        int flag_b=0;                        /*蓝队停止生产标志*/
        int loop_r=0;
        int loop_b=0;                         /*循环计数*/
        cout<<"Case:"<<j+1<<endl;
        while(1){
            if(M[0]==0&&flag_r==0){
                    cout<<setw(3)<<setfill('0')<<clock<<" ";
                    cout<<"red headquarter stops making warriors"<<endl;
                    flag_r=1;
            }
            if(M[0]>=0&&flag_r==0){
                if(pos1==5) pos1=0;                       /*按顺序回头生产*/
                M[0]=M[0]-HP_red[pos1];
                count_red[pos1]=count_red[pos1]+1;
            }
            loop_b=0;
            loop_r=0;
            while(M[0]<0&&flag_r==0){
                M[0]=M[0]+HP_red[pos1];
                pos1++;
                if(pos1==5) pos1=0;
                loop_r++;                                   /*试图制造下一个*/
                if(loop_r==5){
                    cout<<setw(3)<<setfill('0')<<clock<<" ";
                    cout<<"red headquarter stops making warriors"<<endl;
                    flag_r=1;
                    break;
                }
                M[0]=M[0]-HP_red[pos1];
                if(M[0]>=0&&flag_r==0)
                    count_red[pos1]=count_red[pos1]+1;
            }

            if(M[0]>=0&&flag_r==0){
                cout<<setw(3)<<setfill('0')<<clock<<" ";
                cout<<color[k]<<" "<<soldier_red[pos1]<<" "<<clock+1<<" "<<"born with strength "<<HP_red[pos1]<<","<<count_red[pos1]<<" "
                <<soldier_red[pos1]<<" in "<<color[k]<<" headquarter"<<endl;
                pos1++;
            }

            k++;
            if(M[1]==0&&flag_b==0){
                cout<<setw(3)<<setfill('0')<<clock<<" ";
                cout<<"blue headquarter stops making warriors"<<endl;
                break;
            }
            if(M[1]>=0&&flag_b==0){
                if(pos2==5) pos2=0;                       /*按顺序回头生产*/
                M[1]=M[1]-HP_blu[pos2];
                count_blu[pos2]=count_blu[pos2]+1;
            }
            while(M[1]<0&&flag_b==0){
                M[1]=M[1]+HP_blu[pos2];
                pos2++;
                if(pos2==5) pos2=0;
                loop_b++;
                if(loop_b==5)   {
                    cout<<setw(3)<<setfill('0')<<clock<<" ";
                    cout<<"blue headquarter stops making warriors"<<endl;      /*如果无可制造,退出*/
                    flag_b=1;
                    break;
                }
                M[1]=M[1]-HP_blu[pos2];
                if(M[1]>=0&&flag_b==0)
                    count_blu[pos2]=count_blu[pos2]+1;
            }
            if(M[1]>=0&&flag_b==0){
                cout<<setw(3)<<setfill('0')<<clock<<" ";
                cout<<color[k]<<" "<<soldier_blu[pos2]<<" "<<clock+1<<" "<<"born with strength "<<HP_blu[pos2]<<","<<count_blu[pos2]<<" "
                <<soldier_blu[pos2]<<" in "<<color[k]<<" headquarter"<<endl;
                pos2++;
            }
            clock++;
            k=0;
            if(flag_b==1&&flag_r==1)    break;
        }
        clock=0;
        for(int i=0;i<5;i++){
            count_red[i]=0;        /*清零*/
            count_blu[i]=0;
        }
    }

    return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值