魔兽世界之备战 题解

Description

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

红司令部,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武士。(为简单起见,不考虑单词的复数形式)注意,每制造出一个新的武士,都要输出此时司令部里共有多少个该种武士。

  1. 司令部停止制造武士

输出样例: 010 red headquarter stops making warriors

表示在10点整,红方司令部停止制造武士

输出事件时:

首先按时间顺序输出;

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

Input

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

每组测试数据共两行。

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

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

Output

对每组测试数据,要求输出从0时0分开始,到双方司令部都停止制造武士为止的所有事件。

对每组测试数据,首先输出"Case:n" n是测试数据的编号,从1开始 ,每个Case后面输出一个空行。

接下来按恰当的顺序和格式输出所有事件。每个事件都以事件发生的时间开头,时间以小时为单位,有三位。

Sample Input

1
20
3 4 5 6 7

Sample Output

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

Code
/*离亭晚-2021-02-27 00:21:03*/
import java.util.LinkedHashMap;
import java.util.Scanner;
abstract class Command{
    LinkedHashMap<Integer,String> history = new LinkedHashMap<>();//备忘武士制造<时间,具体事件>历史
    String cityName;
    int countIceman = 0,countLion = 0,countWolf = 0,countNinja = 0,countDragon = 0;
    int cityPower,icemanPower,lionPower,wolfPower,ninjaPower,dragonPower;
    boolean nextCreate = true;
    int lowestPower;
    int number = 0, time = 0;
    public Command(int cityPower,int dragonPower,int ninjaPower,int icemanPower,int lionPower,int wolfPower,String cityName){
        this.cityPower = cityPower;
        this.dragonPower = dragonPower;
        this.ninjaPower = ninjaPower;
        this.icemanPower = icemanPower;
        this.lionPower = lionPower;
        this.wolfPower = wolfPower;
        this.cityName = cityName;
        lowestPower = getLowestPower();
        createCycle();
    }
    /*
    如果司令部中的生命元不足以制造某个按顺序应该制造的武士,那么司令部就试图制造下一个。如果所有武士都不能制造了,则司令部停止制造武士
    --Command总生命元不足制造当前武士时,仍需要继续寻找...(而非即刻跳出循环)。因为可能存在下一个的下一个武士满足制造条件
    因此,需要先找出最低生命元的武士,getLowestPower()结合createCycle()、judgeNextCreate以实现题目要求,
    其中,createCycle在父类中是抽象方法,具体方法在子类中实现
    */
    public abstract void createCycle();
    public int getLowestPower(){
        int tmp = 100000;
        if(tmp>dragonPower) tmp = dragonPower;
        if(tmp>ninjaPower)  tmp = ninjaPower;
        if(tmp>icemanPower) tmp = icemanPower;
        if(tmp>lionPower)   tmp = lionPower;
        if(tmp>wolfPower)   tmp = wolfPower;
        return tmp;
    }
    public int getTime(){
        return time++;
    }
    public void judgeNextCreate(){
        if(cityPower>=lowestPower) nextCreate =  true;
        else nextCreate = false;
    }
    public void createIceman(){
        if(cityPower>=icemanPower){
            countIceman++;
            number++;
            printfSuccess("iceman",countIceman,icemanPower);
            cityPower -= icemanPower;
            judgeNextCreate();
        }
    }
    public void createLion(){
        if(cityPower>=lionPower){
            countLion++;
            number++;
            printfSuccess("lion",countLion,lionPower);
            cityPower -= lionPower;
            judgeNextCreate();
        }
    }
    public  void createWolf(){
        if(cityPower>=wolfPower){
            countWolf++;
            number++;
            printfSuccess("wolf",countWolf,wolfPower);
            cityPower -= wolfPower;
            judgeNextCreate();
        }
    }
    public void createNinja(){
        if(cityPower>=ninjaPower){
            countNinja++;
            number++;
            printfSuccess("ninja",countNinja,ninjaPower);
            cityPower -= ninjaPower;
            judgeNextCreate();
        }
    }
    public void createDragon(){
        if(cityPower>=dragonPower){
            countDragon++;
            number++;
            printfSuccess("dragon",countDragon,dragonPower);
            cityPower -= dragonPower;
            judgeNextCreate();
        }
    }
    public void printfSuccess(String soldier,int countSoldier,int soldierPower){
        String s = cityName+" "+soldier+" "+number+" born with strength "+soldierPower+","+countSoldier+" "+soldier+" in "+cityName+" headquarter" ;
        history.put(getTime(),s);
    }
    public void printfFails(){
        String s = cityName+" headquarter stops making warriors";
        history.put(getTime(),s);
    }
}
/*
class BlueCommand与class RedCommand子类继承Command父类,但需重写createCycle()方法,并在其中按不同次序调用各Create方法,以实现:
“红方司令部按照iceman、lion、wolf、ninja、dragon的顺序循环制造武士。
蓝方司令部按照lion、dragon、ninja、iceman、wolf的顺序循环制造武士。”
*/
 class RedCommand extends Command{
     public RedCommand(int cityPower, int dragonPower, int ninjaPower, int icemanPower, int lionPower, int wolfPower, String cityName) {
         super(cityPower, dragonPower, ninjaPower, icemanPower, lionPower, wolfPower, cityName);
     }
     @Override
     public void createCycle(){
         while(nextCreate){//next,可以是当前下一个或下一个的下一个...
             createIceman();
             createLion();
             createWolf();
             createNinja();
             createDragon();
         }
         printfFails();
     }
 }
class BlueCommand extends Command{
    public BlueCommand(int cityPower, int dragonPower, int ninjaPower, int icemanPower, int lionPower, int wolfPower, String cityName) {
        super(cityPower, dragonPower, ninjaPower, icemanPower, lionPower, wolfPower, cityName);
    }
    @Override
    public void createCycle(){
        while(nextCreate){
            createLion();
            createDragon();
            createNinja();
            createIceman();
            createWolf();
        }
        printfFails();
    }
}
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        for (int i = 1; i <= T; i++) {
            int cityPower = sc.nextInt();
            int dragonPower = sc.nextInt();
            int ninjaPower = sc.nextInt();
            int icemanPower = sc.nextInt();
            int lionPower = sc.nextInt();
            int wolfPower = sc.nextInt();
            RedCommand red = new RedCommand(cityPower,dragonPower,ninjaPower,icemanPower,lionPower,wolfPower,"red");
            BlueCommand blue = new BlueCommand(cityPower,dragonPower,ninjaPower,icemanPower,lionPower,wolfPower,"blue");
            int redHistorySize = red.history.size()-1;
            int blueHistorySize = blue.history.size()-1;
            int times = 0;

            System.out.println("Case:"+i);
            while(redHistorySize>=0||blueHistorySize>=0){
                if(red.history.containsKey(times)){
                    String time = String.format("%3d",times).replace(" ","0");
                    System.out.println(time +" " +red.history.get(times));
                }
                if(blue.history.containsKey(times)){
                    String time = String.format("%3d",times).replace(" ","0");
                    System.out.println(time +" " +blue.history.get(times));
                }
                times++;
                redHistorySize--;
                blueHistorySize--;
            }
        }
    }
}
输出测试

数据输出

待测1196
END
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
问题描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为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。 武士降生后就朝对方司令部走,在经过的城市如果遇到敌人(同一时刻每个城市最多只可能有1个蓝武士和一个红武士),就会发生战斗。每次战斗只有一方发起主动进攻一次。被攻击者生命值会减去进攻者的攻击力值和进攻者手中sword的攻击力值。被进攻者若没死,就会发起反击,被反击者的生命值要减去反击者攻击力值的一半(去尾取整)和反击者手中sword的攻击力值。反击可能致敌人于死地。 如果武士在战斗中杀死敌人(不论是主动进攻杀死还是反击杀死),则其司令部会立即向其发送8个生命元作为奖励,使其生命值增加8。当然前提是司令部得有8个生命元。如果司令部的生命元不足以奖励所有的武士,则优先奖励距离敌方司令部近的武士。 如果某武士在某城市的战斗中杀死了敌人,则该武士的司令部立即取得该城市中所有的生命元。注意,司令部总是先完成全部奖励工作,然后才开始从各个打了胜仗的城市回收生命元。对于因司令部生命元不足而领不到奖励的武士,司令部也不会在取得战利品生命元后为其补发奖励。 如果一次战斗的结果是双方都幸存(平局),则双方都不能拿走发生战斗的城市的生命元。 城市可以插旗子,一开始所有城市都没有旗子。在插红旗的城市,以及编号为奇数的无旗城市,由红武士主动发起进攻。在插蓝旗的城市,以及编号为偶数的无旗城市,由蓝武士主动发起进攻。 当某个城市有连续两场战斗都是同一方的武士杀死敌人(两场战斗之间如果有若干个战斗时刻并没有发生战斗,则这两场战斗仍然算是连续的;但如果中间有平局的战斗,就不算连续了) ,那么该城市就会插上胜方的旗帜,若原来插着败方的旗帜,则败方旗帜落下。旗帜一旦插上,就一直插着,直到被敌人更换。一个城市最多只能插一面旗帜,旗帜没被敌人更换前,也不会再次插同颜色的旗。 各种武器有其特点: sword武器的初始攻击力为拥有它的武士的攻击力的20%(去尾取整)。但是sword每经过一次战斗(不论是主动攻击还是反击),就会变钝,攻击力变为本次战斗前的80% (去尾取整)。sword攻击力变为0时,视为武士失去了sword。如果武士降生时得到了一个初始攻击力为0的sword,则视为武士没有sword. arrow有一个攻击力值R。如果下一步要走到的城市有敌人,那么拥有arrow的武士就会放箭攻击下一个城市的敌人(不能攻击对方司令部里的敌人)而不被还击。arrow使敌人的生命值减少R,若减至小于等于0,则敌人被杀死。arrow使用3次后即被耗尽,武士失去arrow。两个相邻的武士可能同时放箭把对方射死。 拥有bomb的武士,在战斗开始前如果判断自己将被杀死(不论主动攻击敌人,或者被敌人主动攻击都可能导致自己被杀死,而且假设武士可以知道敌人的攻击力和生命值),那么就会使用bomb和敌人同归于尽。武士不预测对方是否会使用bomb。 武士使用bomb和敌人同归于尽的情况下,不算是一场战斗,双方都不能拿走城市的生命元,也不影响城市的旗帜。 不同的武士有不同的特点。 dragon可以拥有一件武器。编号为n的dragon降生时即获得编号为 n%3 的武器。dragon还有“士气”这个属性,是个浮点数,其值为它降生后其司令部剩余生命元的数量除以造dragon所需的生命元数量。dragon 在一次在它主动进攻的战斗结束后,如果还没有战死,而且士气值大于0.8,就会欢呼。dragon每取得一次战斗的胜利(敌人被杀死),士气就会增加0.2,每经历一次未能获胜的战斗,士气值就会减少0.2。士气增减发生在欢呼之前。 ninjia可以拥有两件武器。编号为n的ninjia降生时即获得编号为 n%3 和 (n+1)%3的武器。ninja 挨打了也从不反击敌人。 iceman有一件武器。编号为n的iceman降生时即获得编号为 n%3 的武器。iceman 每前进两步,在第2步完成的时候,生命值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值